前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • 基础篇

    • 环境搭建
    • node部署
    • 基础应用
  • 内置模块

    • 1.0 本地路径处理 path
    • 2.0 文件系统操作 fs
    • 3.1 基础调试 console
    • 3.2 本地调试远程服务器上的Node代码
    • 4.1 网络服务 http
    • 4.2 网络服务 http res
    • 4.3 网络服务 http req
    • 4.4 网络服务 http server
    • 4.5 网络服务 http client
    • 4.6 网络服务 https
    • 4.7 网络TCP net
    • 4.8 网络UDP dgram
    • 4.9 域名解析 dns
    • 5.0 网络地址解析 url
    • 5.1 URL查询字符串 querystring
    • 6.1 流操作 stream
    • 6.2 逐行读取 readline
    • 7.1 进程相关 process
    • 7.2 子进程 child
    • 8.1 二进制数据 buffer
    • 8.2 二进制解码 string_decoder
    • 9.1 事件机制 events
    • 9.2 实用工具模块 util
    • 9.3 数据加密 crypto
    • 9.4 MD5入门介绍及crypto模块的应用
    • 9.4 资源压缩 zlib
    • 9.5 集群 cluster
    • 9.6 v8
  • 进阶篇

    • 5分钟入门非对称加密用法
    • cluster
    • cookie_parser深入
    • crypto模块之理论篇
    • express+cookie_parser签名机制深入剖析
    • express+session实现简易身份认证
    • https
    • log4js入门实例
    • node8_napi
    • 使用 async 控制并发
    • 使用 eventproxy 控制并发
    • 使用 superagent 与 cheerio 完成简单爬虫
    • 基于express+muter的文件上传
    • 将图片转成datauri嵌入到html
    • 常用中间件 body_parser 实现解析
    • 日志模块morgan
    • 服务端字符编解码&乱码处理 charset_enc_dec
    • 测试用例mocha,should,istanbul
    • 调试日志打印debug模块
  • Express

    • 1.1 Express概览篇
    • 1.2 Express
  • Koa2

    • 1.0 koa2概览篇
    • 1.1 快速开始
    • 1.2 async await使用
    • 1.3 koa2简析结构
    • 1.4 koa中间件开发与使用
    • 10.1 单元测试
    • 11.1 开发debug
    • 12.1 快速启动
    • 12.2 框架设计
    • 12.3 分层操作
    • 12.4 数据库设计
    • 12.5 路由设计
    • 12.6 webpack4环境搭建
    • 12.7 使用react
    • 12.8 登录注册功能实现
    • 12.9 session登录态判断处理
    • 13.1 import export使用
    • 2.1 原生koa2实现路由
    • 2.2 koa router中间
    • 3.1 GET请求数据获取
    • 3.2 POST请求数据获取
    • 3.3 koa bodyparser中间件
    • 4.1 原生koa2实现静态资源服务器
    • 4.2 koa static中间件
    • 5.1 koa2使用cookie
    • 5.2 koa2实现session
    • 6.1 koa2加载模板引擎
    • 6.2 ejs模板引擎
    • 7.1 busboy模块
    • 7.2 上传文件简单实现
    • 7.3 异步上传图片实现
    • 8.1 mysql模块
    • 8.2 async await封装使用mysql
    • 8.3 项目建表初始化
    • 9.1 原生koa2实现JSONP
    • 9.2 koa jsonp中间件
  • 其他

    • 操作数据库
    • Session 与 Token
    • Cookie、Session、Token、JWT
    • Socket

# 本地调试远程服务器上的Node代码

30 秒速记

  • 现代做法:服务器上 node --inspect=127.0.0.1:9229 app.js,本地 ssh -L 9229:127.0.0.1:9229 user@host,再用 chrome://inspect 或 VS Code 连 localhost:9229
  • 版本差异:老的 node --debug / node debug / node-inspector 基于旧调试协议,Node 8 起已移除,现在统一用 Inspector 协议(--inspect、node inspect)
  • 调试端口绝不能绑 0.0.0.0 暴露公网,连上的人可以在你的进程里执行任意代码
  • 断点会暂停整个事件循环,这个实例上所有请求都会卡住,只在摘掉流量的实例或副本上下断点
  • 已经在跑的进程可以 kill -USR1 <pid> 临时打开调试(Linux/macOS);本地代码版本要和线上一致,否则断点会错位

远程调试的思路是:服务器上的 Node 只在本机回环地址开调试端口,本地通过 SSH 隧道把端口转发过来,再用 Chrome DevTools 或 VS Code 连上去。 这样调试端口从不暴露在公网上,安全性靠 SSH 保证。老教程里的 --debug 和 node-inspector 已经淘汰,现在都是 --inspect。真正要小心的是断点:Node 是单线程的,断点一停整个进程都停,线上实例下断点等于让它挂掉,所以要么摘流量,要么拉个副本复现,线上优先靠日志和监控。

理解「本地调试远程服务器上的Node代码」时,要先明确输入、运行阶段和可观察输出。这里的交互实验会分别执行正常路径与失败路径,并把 Node.js 的关键状态变化和同屏代码对应起来;不能只记命令名称。

工程中还要验证退出码、资源清理和异常输入。属于 network 场景的配置应保持最小可复现,并在开发环境与 CI 中使用相同命令复跑,避免把平台差异或隐式默认值带到线上。

远程调试 Node 的完整步骤,按现在的 Inspector 协议来做:

  1. 在服务器上启动进程时打开调试,只绑本机回环地址:
node --inspect=127.0.0.1:9229 app.js
# Debugger listening on ws://127.0.0.1:9229/xxxx-xxxx
@前端进阶之旅: 代码已经复制到剪贴板

如果进程已经在跑,不想重启,可以发信号临时打开:

kill -USR1 <pid>
@前端进阶之旅: 代码已经复制到剪贴板
  1. 在本地开一个 SSH 隧道,把本地的 9229 转发到服务器的 127.0.0.1:9229:
ssh -N -L 9229:127.0.0.1:9229 user@your-server
@前端进阶之旅: 代码已经复制到剪贴板
  1. 本地连接调试器,二选一:
  • Chrome 打开 chrome://inspect,在 Remote Target 里点 inspect
  • VS Code 的 launch.json 加一个 attach 配置:
{
  "type": "node",
  "request": "attach",
  "name": "Attach Remote",
  "address": "localhost",
  "port": 9229,
  "localRoot": "${workspaceFolder}",
  "remoteRoot": "/srv/app"
}
@前端进阶之旅: 代码已经复制到剪贴板

localRoot 和 remoteRoot 告诉 VS Code 本地哪个目录对应服务器上哪个目录,配错了断点就是灰的。

几个版本上的变化要知道:node --debug、node debug 和 node-inspector 用的是旧的 V8 Debugger 协议,Node 8 起已经移除;命令行调试现在是 node inspect app.js,命令(next、cont、step、out、repl、watch)基本沿用。

最后是安全和稳定性:调试端口能执行任意代码,不能对公网开放;断点会让整个进程停下,只在摘掉流量的实例或者专门的复现环境里用。线上问题优先看日志、指标、trace,需要现场信息时用 --cpu-prof、--heapsnapshot-signal 或 process.report 生成诊断文件,不影响正常服务。

面试官追问

追问 1为了方便,把服务器启动参数改成 --inspect=0.0.0.0:9229,有什么问题?
参考回答

任何能访问这个端口的人都能连进来执行任意代码,相当于把服务器的 shell 送出去了。只绑 127.0.0.1,本地通过 ssh -L 隧道访问,用完关掉。

追问 2在线上实例上打了个断点,接着用户反馈整个服务卡死,为什么?
参考回答

断点暂停的是整个 JS 线程,事件循环停了,这个实例上所有请求都在排队。先从负载均衡上摘掉这个实例再调;能用日志、--cpu-prof 或者堆快照解决的,就别下断点。

追问 3服务已经在跑,启动时没加 --inspect,不想重启怎么办?
参考回答

Linux/macOS 上 kill -USR1 <pid>,进程会在 127.0.0.1:9229 打开调试器,日志里会打出 Debugger listening on ws://...。之后照样走 SSH 隧道连。

追问 4连上了,但断点打在 src/user.ts 上一直不生效,为什么?
参考回答

线上跑的是编译后的 dist 代码,要有对应的 source map,而且本地代码要和线上部署的那个提交完全一致,不然行号对不上。先确认 commit,再看 VS Code 的 outFiles 配得对不对。

追问 5调完之后发现 9229 端口还被占着,下一次启动报 EADDRINUSE,怎么处理?
参考回答

多半是带 --inspect 的旧进程没退干净,lsof -i :9229 找到进程结束掉。重启要换端口可以 --inspect=127.0.0.1:0,让系统随机分配一个。

# 写在前面

30 秒速记

  • 三种断点调试入口:内置命令行调试器 / VS Code 这类 IDE / 浏览器 DevTools(老版本靠 node-inspector)
  • 本质是同一件事:Node 进程开一个调试端口,调试客户端连上去下断点、看变量
  • 版本分水岭:Node 6.3 前是旧 debug 协议(--debug,端口 5858);之后是 Inspector 协议(--inspect,端口 9229),Node 8 起旧协议直接移除
  • 远程调试 = 远端开端口 + 本地客户端连过去;端口只绑 127.0.0.1,走 SSH 隧道
  • 线上排查优先日志、指标、trace,断点只在隔离实例上用

Node 的几种断点调试方式只是客户端不同,底层都是「进程开调试端口,客户端连上去」。 命令行调试器、VS Code、浏览器 DevTools 本质都是调试协议的客户端,区别只在界面顺不顺手。这里有个版本坑:早年教程里的 --debug-brk、node-inspector 走的是旧协议,Node 8 之后已经跑不起来了,现在统一用 --inspect。搞懂这一点,远程调试就不神秘了,无非是把端口安全地接到本地。

谈到node断点调试,目前主要有三种方式,通过node内置调试工具、通过IDE(如vscode)、通过node-inspector,三者本质上差不多。本文着重点在于介绍 如何在本地通过node-inspector 调试远程服务器上的node代码。

在进入主题之前,首先会对三种调试方式进行入门讲解,方便新手理解后面的内容。至于老司机们,可以直接跳到主题去。

面试官追问

追问 1命令行、VS Code、DevTools 下断点,背后原理一样吗?
参考回答

一样。都是 Node 进程用 --inspect 开一个 WebSocket 调试端口,客户端按 Inspector 协议发「设断点」「继续执行」这类指令,换客户端不换原理。

追问 2照着老教程装了 node-inspector,在 Node 18 上连不上,为什么?
参考回答

node-inspector 依赖旧的 --debug 协议,Node 8 起这个协议就被移除了,项目也早停止维护。直接 node --inspect app.js,然后在 Chrome 里打开 chrome://inspect 就行。

追问 3远程调试最容易出事的地方在哪?
参考回答

把调试端口开到公网。Inspector 能在进程里执行任意代码,谁连上谁就拿到了这台机器上这个进程的权限。端口只绑 127.0.0.1,本地用 ssh -L 转发过来。

追问 4线上接口偶发报错,直接在生产实例上挂断点查可以吗?
参考回答

一般不这么干。断点一停,整个事件循环都停了,这个实例上所有请求一起卡住。先看日志和 trace,真要断点就摘掉一个实例的流量,或者起一个隔离副本复现。

# 方式一:内置debug功能

30 秒速记

  • 现在的入口:node inspect app.js(Node 8 前是 node debug,已废弃)
  • 单步四件套:n/next 下一行、c/cont 到下一个断点、s/step 进函数、o/out 跳出函数
  • 看变量:输入 repl 进入求值模式,敲变量名就能看值,Ctrl+C 退回调试命令
  • 监视:watch('expr') 加、watchers 看、unwatch('expr') 删;restart 重跑不用退出
  • 远程:服务端
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • 基础篇

    • 环境搭建
    • node部署
    • 基础应用
  • 内置模块

    • 1.0 本地路径处理 path
    • 2.0 文件系统操作 fs
    • 3.1 基础调试 console
    • 3.2 本地调试远程服务器上的Node代码
      • 写在前面
      • 方式一:内置debug功能
        • 进入调试模式(在第1行断点)
        • 进入调试模式(在第n行断点)
        • 执行下一步
        • 跳到下一个断点
        • 查看某个变量的值
        • 添加/删除watch
        • 进入/跳出函数(step in、step out)
        • 多个文件断点
        • 重新运行
        • 远程调试
      • 方式二:通过IDE(vscode)
      • 方式三:通过node-inspector
      • 通过node-inspector调试远程代码
      • 相关链接
      • 可运行示例:只监听回环地址,再通过 SSH 隧道连接
    • 4.1 网络服务 http
    • 4.2 网络服务 http res
    • 4.3 网络服务 http req
    • 4.4 网络服务 http server
    • 4.5 网络服务 http client
    • 4.6 网络服务 https
    • 4.7 网络TCP net
    • 4.8 网络UDP dgram
    • 4.9 域名解析 dns
    • 5.0 网络地址解析 url
    • 5.1 URL查询字符串 querystring
    • 6.1 流操作 stream
    • 6.2 逐行读取 readline
    • 7.1 进程相关 process
    • 7.2 子进程 child
    • 8.1 二进制数据 buffer
    • 8.2 二进制解码 string_decoder
    • 9.1 事件机制 events
    • 9.2 实用工具模块 util
    • 9.3 数据加密 crypto
    • 9.4 MD5入门介绍及crypto模块的应用
    • 9.4 资源压缩 zlib
    • 9.5 集群 cluster
    • 9.6 v8
  • 进阶篇

    • 5分钟入门非对称加密用法
    • cluster
    • cookie_parser深入
    • crypto模块之理论篇
    • express+cookie_parser签名机制深入剖析
    • express+session实现简易身份认证
    • https
    • log4js入门实例
    • node8_napi
    • 使用 async 控制并发
    • 使用 eventproxy 控制并发
    • 使用 superagent 与 cheerio 完成简单爬虫
    • 基于express+muter的文件上传
    • 将图片转成datauri嵌入到html
    • 常用中间件 body_parser 实现解析
    • 日志模块morgan
    • 服务端字符编解码&乱码处理 charset_enc_dec
    • 测试用例mocha,should,istanbul
    • 调试日志打印debug模块
  • Express

    • 1.1 Express概览篇
    • 1.2 Express
  • Koa2

    • 1.0 koa2概览篇
    • 1.1 快速开始
    • 1.2 async await使用
    • 1.3 koa2简析结构
    • 1.4 koa中间件开发与使用
    • 10.1 单元测试
    • 11.1 开发debug
    • 12.1 快速启动
    • 12.2 框架设计
    • 12.3 分层操作
    • 12.4 数据库设计
    • 12.5 路由设计
    • 12.6 webpack4环境搭建
    • 12.7 使用react
    • 12.8 登录注册功能实现
    • 12.9 session登录态判断处理
    • 13.1 import export使用
    • 2.1 原生koa2实现路由
    • 2.2 koa router中间
    • 3.1 GET请求数据获取
    • 3.2 POST请求数据获取
    • 3.3 koa bodyparser中间件
    • 4.1 原生koa2实现静态资源服务器
    • 4.2 koa static中间件
    • 5.1 koa2使用cookie
    • 5.2 koa2实现session
    • 6.1 koa2加载模板引擎
    • 6.2 ejs模板引擎
    • 7.1 busboy模块
    • 7.2 上传文件简单实现
    • 7.3 异步上传图片实现
    • 8.1 mysql模块
    • 8.2 async await封装使用mysql
    • 8.3 项目建表初始化
    • 9.1 原生koa2实现JSONP
    • 9.2 koa jsonp中间件
  • 其他

    • 操作数据库
    • Session 与 Token
    • Cookie、Session、Token、JWT
    • Socket
完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

本地调试远程服务器上的Node代码|Nodejs专题系列

# 本地调试远程服务器上的Node代码

30 秒速记

  • 现代做法:服务器上 node --inspect=127.0.0.1:9229 app.js,本地 ssh -L 9229:127.0.0.1:9229 user@host,再用 chrome://inspect 或 VS Code 连 localhost:9229
  • 版本差异:老的 node --debug / node debug / node-inspector 基于旧调试协议,Node 8 起已移除,现在统一用 Inspector 协议(--inspect、node inspect)
  • 调试端口绝不能绑 0.0.0.0 暴露公网,连上的人可以在你的进程里执行任意代码
  • 断点会暂停整个事件循环,这个实例上所有请求都会卡住,只在摘掉流量的实例或副本上下断点
  • 已经在跑的进程可以 kill -USR1 <pid> 临时打开调试(Linux/macOS);本地代码版本要和线上一致,否则断点会错位

远程调试的思路是:服务器上的 Node 只在本机回环地址开调试端口,本地通过 SSH 隧道把端口转发过来,再用 Chrome DevTools 或 VS Code 连上去。 这样调试端口从不暴露在公网上,安全性靠 SSH 保证。老教程里的 --debug 和 node-inspector 已经淘汰,现在都是 --inspect。真正要小心的是断点:Node 是单线程的,断点一停整个进程都停,线上实例下断点等于让它挂掉,所以要么摘流量,要么拉个副本复现,线上优先靠日志和监控。

理解「本地调试远程服务器上的Node代码」时,要先明确输入、运行阶段和可观察输出。这里的交互实验会分别执行正常路径与失败路径,并把 Node.js 的关键状态变化和同屏代码对应起来;不能只记命令名称。

工程中还要验证退出码、资源清理和异常输入。属于 network 场景的配置应保持最小可复现,并在开发环境与 CI 中使用相同命令复跑,避免把平台差异或隐式默认值带到线上。

远程调试 Node 的完整步骤,按现在的 Inspector 协议来做:

  1. 在服务器上启动进程时打开调试,只绑本机回环地址:
node --inspect=127.0.0.1:9229 app.js
# Debugger listening on ws://127.0.0.1:9229/xxxx-xxxx
@前端进阶之旅: 代码已经复制到剪贴板

如果进程已经在跑,不想重启,可以发信号临时打开:

kill -USR1 <pid>
@前端进阶之旅: 代码已经复制到剪贴板
  1. 在本地开一个 SSH 隧道,把本地的 9229 转发到服务器的 127.0.0.1:9229:
ssh -N -L 9229:127.0.0.1:9229 user@your-server
@前端进阶之旅: 代码已经复制到剪贴板
  1. 本地连接调试器,二选一:
  • Chrome 打开 chrome://inspect,在 Remote Target 里点 inspect
  • VS Code 的 launch.json 加一个 attach 配置:
{
  "type": "node",
  "request": "attach",
  "name": "Attach Remote",
  "address": "localhost",
  "port": 9229,
  "localRoot": "${workspaceFolder}",
  "remoteRoot": "/srv/app"
}
@前端进阶之旅: 代码已经复制到剪贴板

localRoot 和 remoteRoot 告诉 VS Code 本地哪个目录对应服务器上哪个目录,配错了断点就是灰的。

几个版本上的变化要知道:node --debug、node debug 和 node-inspector 用的是旧的 V8 Debugger 协议,Node 8 起已经移除;命令行调试现在是 node inspect app.js,命令(next、cont、step、out、repl、watch)基本沿用。

最后是安全和稳定性:调试端口能执行任意代码,不能对公网开放;断点会让整个进程停下,只在摘掉流量的实例或者专门的复现环境里用。线上问题优先看日志、指标、trace,需要现场信息时用 --cpu-prof、--heapsnapshot-signal 或 process.report 生成诊断文件,不影响正常服务。

面试官追问

追问 1为了方便,把服务器启动参数改成 --inspect=0.0.0.0:9229,有什么问题?
参考回答

任何能访问这个端口的人都能连进来执行任意代码,相当于把服务器的 shell 送出去了。只绑 127.0.0.1,本地通过 ssh -L 隧道访问,用完关掉。

追问 2在线上实例上打了个断点,接着用户反馈整个服务卡死,为什么?
参考回答

断点暂停的是整个 JS 线程,事件循环停了,这个实例上所有请求都在排队。先从负载均衡上摘掉这个实例再调;能用日志、--cpu-prof 或者堆快照解决的,就别下断点。

追问 3服务已经在跑,启动时没加 --inspect,不想重启怎么办?
参考回答

Linux/macOS 上 kill -USR1 <pid>,进程会在 127.0.0.1:9229 打开调试器,日志里会打出 Debugger listening on ws://...。之后照样走 SSH 隧道连。

追问 4连上了,但断点打在 src/user.ts 上一直不生效,为什么?
参考回答

线上跑的是编译后的 dist 代码,要有对应的 source map,而且本地代码要和线上部署的那个提交完全一致,不然行号对不上。先确认 commit,再看 VS Code 的 outFiles 配得对不对。

追问 5调完之后发现 9229 端口还被占着,下一次启动报 EADDRINUSE,怎么处理?
参考回答

多半是带 --inspect 的旧进程没退干净,lsof -i :9229 找到进程结束掉。重启要换端口可以 --inspect=127.0.0.1:0,让系统随机分配一个。

# 写在前面

30 秒速记

  • 三种断点调试入口:内置命令行调试器 / VS Code 这类 IDE / 浏览器 DevTools(老版本靠 node-inspector)
  • 本质是同一件事:Node 进程开一个调试端口,调试客户端连上去下断点、看变量
  • 版本分水岭:Node 6.3 前是旧 debug 协议(--debug,端口 5858);之后是 Inspector 协议(--inspect,端口 9229),Node 8 起旧协议直接移除
  • 远程调试 = 远端开端口 + 本地客户端连过去;端口只绑 127.0.0.1,走 SSH 隧道
  • 线上排查优先日志、指标、trace,断点只在隔离实例上用

Node 的几种断点调试方式只是客户端不同,底层都是「进程开调试端口,客户端连上去」。 命令行调试器、VS Code、浏览器 DevTools 本质都是调试协议的客户端,区别只在界面顺不顺手。这里有个版本坑:早年教程里的 --debug-brk、node-inspector 走的是旧协议,Node 8 之后已经跑不起来了,现在统一用 --inspect。搞懂这一点,远程调试就不神秘了,无非是把端口安全地接到本地。

谈到node断点调试,目前主要有三种方式,通过node内置调试工具、通过IDE(如vscode)、通过node-inspector,三者本质上差不多。本文着重点在于介绍 如何在本地通过node-inspector 调试远程服务器上的node代码。

在进入主题之前,首先会对三种调试方式进行入门讲解,方便新手理解后面的内容。至于老司机们,可以直接跳到主题去。

面试官追问

追问 1命令行、VS Code、DevTools 下断点,背后原理一样吗?
参考回答

一样。都是 Node 进程用 --inspect 开一个 WebSocket 调试端口,客户端按 Inspector 协议发「设断点」「继续执行」这类指令,换客户端不换原理。

追问 2照着老教程装了 node-inspector,在 Node 18 上连不上,为什么?
参考回答

node-inspector 依赖旧的 --debug 协议,Node 8 起这个协议就被移除了,项目也早停止维护。直接 node --inspect app.js,然后在 Chrome 里打开 chrome://inspect 就行。

追问 3远程调试最容易出事的地方在哪?
参考回答

把调试端口开到公网。Inspector 能在进程里执行任意代码,谁连上谁就拿到了这台机器上这个进程的权限。端口只绑 127.0.0.1,本地用 ssh -L 转发过来。

追问 4线上接口偶发报错,直接在生产实例上挂断点查可以吗?
参考回答

一般不这么干。断点一停,整个事件循环都停了,这个实例上所有请求一起卡住。先看日志和 trace,真要断点就摘掉一个实例的流量,或者起一个隔离副本复现。

# 方式一:内置debug功能

30 秒速记

  • 现在的入口:node inspect app.js(Node 8 前是 node debug,已废弃)
  • 单步四件套:n/next 下一行、c/cont 到下一个断点、s/step 进函数、o/out 跳出函数
  • 看变量:输入 repl 进入求值模式,敲变量名就能看值,Ctrl+C 退回调试命令
  • 监视:watch('expr') 加、watchers 看、unwatch('expr') 删;restart 重跑不用退出
  • 远程:服务端 node --inspect-brk=127.0.0.1:9229 app.js,本地经隧道 node inspect 127.0.0.1:9229

内置调试器就是一个命令行版的断点工具,没有 IDE 的时候靠它就能单步看变量。 现在用 node inspect app.js 启动,它会停在第一行,n 走一行、c 跑到下一个断点、s 和 o 进出函数。想看变量就敲 repl,然后直接输变量名。代码里写一句 debugger; 就是一个断点,比命令行里 setBreakpoint 方便。我一般只在服务器上没有图形界面、又不想开端口转发的时候用它,平时还是 DevTools 顺手。

← 3.1 基础调试 console4.1 网络服务 http →

fe