NodeJS Process,信号,退出码

0 阅读3分钟

一、先建立整体概念:Node.js 程序到底在和谁打交道

当你运行:

node app.js

其实发生的是:

  1. 操作系统创建了一个“进程”
  2. 这个进程里运行了 Node.js
  3. Node.js 再执行你的 app.js
  4. Node.js 给你暴露了一个全局对象:process 所以:
  • process不是你自己创建的
  • 他是Node.js提供的"当前进程信息与控制中心"
  • 你可以通过它读取环境信息、接收命令行参数、处理退出、监听信号、操作标准输入输出等 可以把它理解成: || process=你这次Node程序运行时,对当前进程的操作面板 二、 process是什么
  1. process是全局对象,在Node.js里可以直接使用,不需要require;它包含很多信息,比如:
  • 当前进程ID:process.pid;用于排查问题时定位进程,用kill命令给这个进程发信号;多进程程序中区分不同进程;process.ppid:父进程ID。比如你是在shell里启动的Node程序,父进程通常就是shell。
  • 启动参数:process.argv;命令行参数数组
  • 环境变量:process.env环境变量对象;用途:配置数据库地址;配置端口;配置运行环境;存放密钥(生产中常见)
NODE_ENV=production node app.js


console.log(process.env);
console.log(process.env.NODE_ENV);//production

  • 当前工作目录:process.cwd()当前工作目录;他不是当前文件所在目录,而是你从哪个目录执行的命令
  • 平台信息:process.platform当前操作系统平台(win32,linux,darwin)用途写跨平台逻辑;process.arch:CPU架构(c常见:x64,arm64)
  • 退出状态:process.exitCode设置进程退出码,但不立即退出;process.exit(code)立即结束当前进程
  • 标准输入输出
  • 接收到的系统信号
  • 事件循环相关状态

三、process事件

  1. exit事件:当进程即将退出时触发;注意:::在exit事件里,不能再做异步操作;
  • 适合做:最后的同步清理;记录退出码;打印结束日志
  • 不适合做:异步写文件,网络请求,setTimeout
process.on('exit', (code) => {
  console.log('进程即将退出,退出码:', code);
});
  1. beforeExit事件(实际开发中不常用,更多用于理解Node的退出机制,或者做一些高级控制) 当NodeJS事件循环要空了,准备退出时触发触发。和exit的区别是:
  • beforeExit时,进程还没真正退出
  • 你可以在里面继续安排异步任务,让进程继续活着
  • exit时,已经来不及了
  1. uncaughtException处理未捕获异常
  • 这个事件不适合拿来当正常错误处理机制,原因是:
    • 一旦出现未捕获异常,程序状态可能已经不可靠
    • 某些资源可能半初始化,半销毁
    • 继续运行可能更危险
  • 更合理的做法通常是:
    • 记录日志
    • 做必要清理
    • 退出进程
    • 让外部守护进程或重启
  1. unhandledRejection:处理未被处理的Promise拒绝 四、需要记住的核心代码模板
  • 获取命令行参数
const args = process.env.slice(2)
  • 读取环境变量
const port = process.env.PORT||3000;
  • 输出正常信息和错误信息
process.stdout.write('正常输出\n')
process.stderr.write('错误输出\n')

console.log('正常输出');
console.error('错误输出')
  • 监听Ctrl+C
process.on('SIGINT',()=>{
console.log('收到 SIGINT')
process.exit(0)
})
* 设置退出码,但不立刻退出
```js
process.exitCode = 1
  • 从标准输入读一行
process.stdin.oncee('data',(chunk)=>{
const input = chunk.toString().trim();
console.log(input)
})
* 优雅关闭服务
```js
process.on('SIGTERM',()=>{
server.close(()=>{
process.exit(0)})
})