背景

nodejs 4.x 的项目, 需要升级到6.9.5(当时最新的稳定版本)以改善性能和可靠性.

业务中使用到了co, 进程使用 pm2 管理.

升级nodejs版本

确保构建脚本能够使用nvm安装nodejs 6.9.5, 本地运行基本ok

从 co 的问题开始

UnhandledPromiseRejectionWarning: Cannot read property 'done' of undefined
复制代码

服务启动时即产生上述报警信息, 服务不可用, 通过搜索发现是存在某个promise最终reject了, 但是没有catch. 知道直接原因是这样, 但没啥帮助, 我上哪去找这种特点的代码.

考虑断点调试

process.on('unhandledRejection', function(reason, p){console.log('=======================');console.log(reason);console.log(p);
});
复制代码

上述代码加到服务开始启动, 本地调试启动, 发现一切正常 -_-b

不复现问题, 回顾整个问题, 目测可能是测试环境问题, 先看看nodejs版本吧

console.log(process.versions)
复制代码

竟然nodejs版本还是旧版本

pm2 的问题

能决定nodejs版本的途径就只有进程启动了, 哪问题就落到 pm2 这边了, 去检查pm2的进程配置

> pm2 show myapp_name
│ interpreter       │ node
│ interpreter args  │ --harmony
....
│ exec mode         │ cluster_mode
│ node.js version   │ 4.4.2
复制代码

果然版本有问题, 考虑pm2这种进程管理模型, daemon进程启动后, 再逐个启动worker进程, 而 exec mode: cluster_mode 意味着它使用了nodejs的cluster模块来启动子进程.

进一步的, cluster启动子进程是用fork()启动的, 子进程的版本和父进程版本应该是一致的. 大概率是这个原因.

简单重启daemon进程的办法是 pm2 kill 干掉daemon和所有worker进程后, 重新pm2 start. 一番折腾后的结论:

  1. daemon进程更新, 除了 pm2 kill && pm2 ping可以重启daemon外, 还可以 pm2 update 它还会使用当前版本pm2
  2. 想要让app生效还是建议重新添加app, pm2 delete app.json && pm2 start app.json

测试环境 重启了pm2 daemon进程后, 启动仍旧是前文遇到的报警, 但 node.js version 输出是符合预期了.

虽然没解决问题, 但升级版本是必须的. 继续看看, 收集线索

回到 co 的问题

现在nodejs版本一致, 但是测试环境报警, 本地不复现, 可能还是环境问题, 继续看进程配置, 发现 interpreter args: --harmony

这个是旧版本nodejs为了兼容新的特性加的开关, 考虑到错误堆栈是从co中过来的, 查看co的文档

按理v4+之后就不需要加这个开关, 暂且不关心为什么加这个开关, 目前能找到的差异就是这个地方, 先本地加上这个开关运行看看

结果复现相同的报警, 本地和测试环境现象一致

接下来就好办了, 到app.json中删除这段配置, pm2 delete app.json && pm2 start app.json 重新启动app, 问题解决.

总结

  1. pm2 cluster_mode 升级nodejs时需要同步更新daemon进程
  2. worker进程的配置也需要手工更新
  3. nodejs不会保证部分实验性开关的兼容性

实际遇到的环境问题可能都是混杂多个关键原因, 必须得解决所有的原因才能正常工作.

错误才是常态, 正确是一连串的偶然组合在一起

遗留疑问: --harmony 怎么加上去的

了解cluster的同学应该知道 fork() 只有一个参数 环境变量, 那就有些奇怪的地方了.

一种可能是 pm2 daemon 启动时加上去的, 但也不合逻辑, daemon可能会管理多个项目, 有的是cluster, 有的不是.

只是猜测显然不行, 看源码吧

God.nodeApp = function nodeApp(env_copy, cb){var clu = null;console.log('Starting execution sequence in -cluster mode- for app name:%s id:%s',env_copy.name,env_copy.pm_id);if (env_copy.node_args && Array.isArray(env_copy.node_args)) {// 注意下面这行cluster.settings.execArgv = env_copy.node_args;}env_copy._pm2_version = pkg.version;try {// node.js cluster clients can not receive deep-level objects or arrays in the forked process, e.g.:// { "args": ["foo", "bar"], "env": { "foo1": "bar1" }} will be parsed to// { "args": "foo, bar", "env": "[object Object]"}// So we passing a stringified JSON here.clu = cluster.fork({pm2_env: JSON.stringify(env_copy)});} catch(e) {God.logAndGenerateError(e);return cb(e);}
复制代码

重新翻看 cluster 的文档, 发现确实存在 cluster.settings


大家好,我是猫眼娱乐前端技术专家-曹宇,我主要负责猫眼娱乐电影选座交易业务前端, 除了大家能看到的各种 Web 页面, 还有小程序端和供应链端. 同时负责猫眼内部的前端基础设施, 质量保证相关工作。

猫眼电影小程序从零发展到票务类别第一, 主要关注点都集中在线上, 这次分享的是一个线上 线下联动的活动, 从开发到上线后遇到的一些有趣的事情, 除了小程序技术的深度应用, 还包括产品 运营层面的思考.

本周六(10月21日)我会做客掘金Bilibili直播间为大家做一场《打码指南:由猫眼线下扫码1分购谈起》的直播。直播中我们也会送出技术图书,大号定制鼠标垫等奖品,欢迎周六下午大家与我们一起交流。

转载于:https://juejin.im/post/5bcd4a99e51d457ab36ced16

升级 Node.js 版本遇到的 co 和 pm2 问题解析相关推荐

  1. Ubuntu 20.04 在线升级node.js版本

    该方法是针对系统中已存在nodejs,由于版本低需要升级可以进行如下操作: · sudo npm install n -g ·sudo n stable 依次执行即可完成node升级 Using Ub ...

  2. 一行命令搞定node.js 版本安装、升级与卸载

    一.安装 wget https://nodejs.org/download/release/v6.10.0/node-v6.10.0-linux-x64.tar.gz 解压到当前目录:(推荐/usr/ ...

  3. node 升级_Node.js 版本知多少?又该如何选择?

    习惯成自然是个魔术师.它对美丽的东西是残酷的,但是对丑陋的东西却是仁慈的.--威达 Node.js 曾出现过与 io.js 的分裂,自合并成立 Node.js 基金会以来,就开始使用 Long Ter ...

  4. 以太坊测试链环境node.js版本

    为什么80%的码农都做不了架构师?>>>    MAC升级Nodejs和Npm到最新版 第一步,先查看本机node.js版本: node -v 第二步,清除node.js的cache ...

  5. windows10下升级node.js和降级Nodejs

    ①windows10下升级node.js 重启之前的项目.刚开始是在用vue的脚手架来构建基于wenbpack的项目,按照vue.js官网上的步骤进行构建,我发现我比别人少了dist文件夹.具体的原因 ...

  6. npm 升级node.js

    升级NPM 到最新 查看npm 版本: npm -v 更新到最新版本: npm install npm@latest -g 升级Node.js 从node官网下载最新node.js 安装包覆盖原理的n ...

  7. 3 分钟掌握 Node.js 版本的区别

    在我们日常开发中,Node.js 使用场景越来越多,大到服务端项目,小到开发工具脚本,所以掌握 Node.js 一些基础知识是非常有必要的. 今天主要聊一下 Node.js 中 LTS 和 Curre ...

  8. Windows系统升级node.js版本

    (1)在cmd使用指令where node 找到node.js安装地址 (2)在以下改地址找到所需的node.js版本,下载解压之后删掉之前的所有文件,把新版本中的全部文件复制过去.注意:一定要全删掉 ...

  9. 限定项目的 Node.js 版本

    限定项目的 Node.js 版本 限定项目运行所需的 Node.js 版本可保证项目在一个稳定可预期的环境中运行,减少不必要的故障.甚至有些依赖库只能工作于某些版本下.同时,不加以限制的话,在多人合作 ...

  10. 使用napi node_使用Napi / node-addon-api和Cmake的独立于Node.js版本的C ++ Native Addon

    使用napi node This is a tutorial for c++ Node-addon-api / Napi addon using cmake.Napi makes it indepen ...

最新文章

  1. ARM嵌入式操作系统启动
  2. 工作中的一次linux防范ddos***___转载
  3. 邮件实现详解(三)------邮件的组织结构
  4. 博客园配置windows live writer,实现本地代码高亮
  5. angular element()
  6. win10安装mysql5.7.15_win10上如何安装mysql5.7.16(解压缩版)
  7. ReflectionPad2d--利用输入边界的反射来填充输入张量
  8. 全网最详细的HBase启动以后,HMaster进程启动了,几秒钟以后自动关闭问题的解决办法(图文详解)
  9. JAVA调用海康威视SDK
  10. iOS crash dSYM
  11. Umi-—前端应用框架(Umi基础)
  12. python查找文件指定内容_python实现在目录中查找指定文件的方法
  13. 聊天别被人家说的“职业技术”忽悠了
  14. 很遗憾,这就是现实!35岁之后软件测试工程师靠什么养家?
  15. java mysql点赞功能_用Java做一个类似于微博QQ空间点赞的功能-Fun言
  16. python pip 安装使用国内镜像源
  17. ADT: Graph 图
  18. 【cookbook pandas】学习笔记 chapter9 grouping,aggregation,filtration,and transformation
  19. 电视直播录播系统,多路电视直播录播解决方案
  20. oracle物理读优化,oracle 性能优化 06_sql优化

热门文章

  1. 【TFS 2017 CI/CD系列 - 01】-- Agent篇
  2. 常见批处理作业调度算法
  3. 手记-数学分析(高等数学)中有关算法效率的公式列举(O,Θ,Ω)
  4. apache支持.htaccess
  5. ASP.net在线购物商城系统完全解析
  6. 杭电多校HDU 6656 Kejin Player(概率DP)题解
  7. Acticles about Interface!
  8. 深入学习c++(虚函数遇到析构函数就退化了)
  9. django后台管理--添加自定义action
  10. React Mixin