Node.js 和 Egg.js 项目远程调试

前言
背景
在开发 Node.js 项目过程中,为了更加快速、方便的定位问题,我们一般都会在开发过程中使用本地调试当前的项目。但是项目如果已经部署到远程的服务器以后,再出现问题,就很难定位问题所在了。因此对远程服务器当前运行的项目进行调试也是一个很现实和重要的需求。
本文假设读者都会使用 Node.js 的本地调试方法和工具,因此重点放在已经运行在远程机器的 Node.js 项目调试方法上。如果不了解本地调试内容,请先了解相关内容后再阅读本文。
环境
- Node.js:12.x;
- Egg.js:2.26.x;
- WebStorm:2019.3.2;
- VSCode:1.42.1;
目标
本文主要讲解对远程 Node.js 项目的调试,包括调试方法和常用的调试工具的使用。
和远程服务器建立 ssh 隧道
其实最直接的办法是直接将用于调试的端口放开,例如默认的进程监听端口是 9229,在服务器防火墙上放行这个端口,但是风险太大,相当于直接把程序的控制权开放给了整个互联网,因此我们需要采取更加安全的方式进行。
开启本地监听
首先开启本地监听。
$ node --inspect server.js
如果是 Egg.js 的话使用以下命令。
$ npm run debug
建立隧道
通过以下命令在本地的 9229 端口和远程服务器的 9229 端口之间建立一条 ssh 的隧道。这样的话只监听本地的 9229 端口就可以调试远程项目了。当然这里本地的 9229 可以换成任意的端口号。
$ ssh -L 9229:localhost:9229 root@<IP or domain>
Egg.js 的项目稍微有一些区别。因为 Egg.js 的项目至少要启动 3 个进程,分别是 master、worker 和 agent,其中 worker 一般会和 CPU 的数量相同。各个进程对应的端口说明如下:
master
调试端口为 9229 或 5858(旧协议);agent
调试端口固定为 5800,可以传递 process.env.EGG_AGENT_DEBUG_PORT 来自定义;worker
调试端口为 master 调试端口递增;
因此,如果我们要实际调试业务代码,不能监听 9229,而应该监听 9230。
IDE 调试
ssh 隧道成功建立以后,我们就可以调试远程项目了。调试工具有很多中,最基础的可以使用 Chrome 自带的调试工具,但是不太方便,因此以下主要讲解 WebStorm 和 VSCode 环境下的调试。
WebStorm
首先创建一个调试的配置,配置的模板选择 Attach to Node.js/Chrome
,详见下图。两个地方需要注意。
- 一个是填写映射到本地的端口号,而不是远程服务器的端口号;
- 二是要填写 Remote URL,地址就是远程服务器项目的路径;
VSCode
VSCode 的配置也比较简单,从插件商店搜索 eggjs
的 Egg.js 项目组官方插件并安装。然后调试的时候选择 Egg attach to remote
。然后同样修改一下本地端口号和远程项目路径即可。
{
"type": "node",
"request": "attach",
"name": "Egg Attach to remote",
"localRoot": "${workspaceRoot}",
"remoteRoot": "/data/projects/iot-back-end",
"address": "localhost",
"protocol": "auto",
"port": 9230
}