IT技术博客大学习 共学习 共进步

管理 Node.js 进程从未如此优雅

Taobao FED | 淘宝前端团队 2019-03-26 09:50:55 浏览 2,027 次

       说到 Node.js 的进程模型,脑子里第一个闪现的可能是 Cluster 模块,亦或是 Master / Worker 进程模型,在长期的使用过程中,我们逐渐发现,这样在应用的开发早晚会有局限性,除了不够优雅之外,每次增减进程或者自定义进程都会产生不可预知的问题。

   在一些特定的场景下,我们甚至在 Master 下面加入了一个 Agent 进程用来运行一些中间件 SDK 。在这些修修补补的过程中,传统的进程间通信,数据交换都变的困难,甚至 Worker 到 Agent 之间通信都无法很优雅的进行。

   除了一些内存共享的通信场景, 也出现了 Worker 进程跑一些定时任务占用时间过长,导致 Web 接口超时等问题(或者系统容量降低)。更有甚者,把定时任务放到 Agent 中去执行,直接拖挂了基础的中间件服务,导致应用全盘崩溃。

   就像下图:

   img | center

   虽然说影响可用性是一方面,但毕竟上面说到的情况也属于软件质量问题,通过充分的测试也可以避免,比较可怕的是进程模型和框架越绑越深。如果你想发布 RPC 服务、做一些任务处理,可能在复杂的进程模型下也没法做到了,只能让 Node.js 做一些 Web Server 的事情,在一定程度上给 Node.js 应用设置了限,不容易进化和发展。

   这也是我们开发 Pandora.js 最直接的原因。

procfile.js

   面对这样的窘迫,从去年春节前后我们就开始准备做一些事情了,当然期间也走了一些弯路,在讨论了多次之后将大部分的场景都理顺了。

   首先, 我们提出了一个进程结构定义文件,我们管它叫 procfile.js

   看到 procfile 这个词有些朋友可能熟悉,这是 Heroku (一个云服务商)进程定义文件的名字。我们也已经忘记是谁提出来要叫 procfile.js 的了,但是我们觉得这个名字还不错,毕竟 procfile 是 Process File 的一种现有简写(我们就不用自己造词了,省了一桩麻烦事)。

   当然把进程交给 Pandora.js 管理,不只是帮你创建进程这么简单,更是:

   Pandora.js 会守护创建出来的进程。

   小到自动重启、切割日志文件、重启次数计数。

   大到 30 多项 Metrics 指标采集、自动的全链路 Trace 追踪、对接现有 APM (比如 Open-Falcon)等等。

   不过我们今天大致讲讲进程相关的设计思考,怎么安装、怎么启动还请到我们 GitHub 中查看文档~

   还有其他部分比如监控、Metrics、Trace 等也要未来再讲啦~

   BTW

   项目地址:https://github.com/midwayjs/pandora ,大家觉得好也去给点个 Star ~~

简单的 procfile.js 例子

   如果要定义一个进程,大致样例是这样的:

   procfile.js

// procfile.js 是一个普通的 Node.js 模块,必须导出一个 function
// function(pandora) 的第一个参数是 pandora,这个对象用于定义我们的进程结构
module.exports = function(pandora) {
  pandora
    // 定义一个进程,名字叫 processA
    .process('processA')

    // 如果 scale 大于 1 ,将使用 Node.js 的 Cluster 模块自动产生进程组
    .scale(1)

    // Node.js 参数
    .argv(['--expose-gc'])

    // 定义进程环境变量,创建出来的进程中可以通过 process.env 获得
    .env({
      ENV_VAR1: 'VALUE_OF_ENV_VAR1'
    })

// 启动顺序
.order(1)

// 这个进程的入口文件地址
.entry('./app.js');

  /*
    pandora
     .process('processB');
    pandora
     .process('processC');
    pandora
     .process('processD');

    and so on so on....
  */
}

   上面简单的定义了一个入口是 ./app.js 的进程叫 processA,这基本和 node ./app.js 一样。

   针对这种场景,我们还提供了另一个更简单的方式。

module.exports = function(pandora) {
  pandora.fork('processA', './app.js');
}

进程伸缩 - Scalable

   大家上面看到了,procfile.js 中定义进程伸缩主要依靠下面的定义:

pandora.process(‘processX’).scale(5);

   上面这个定义的意思是,将名为 processX 的进程扩展 5 份。

   Scale 这个值在 Pandora.js 中很重要,用户并不需要指定哪个进程,需要用 Cluster 模块进行伸缩(使用 Master / Worker 模型),哪个进程直接启动。

   都是 Pandora.js 根据 Scale 这个值自动决定的。

   下图可能更容易理解:

   img | center

未完待续

   这篇只是介绍了进程定义的一部分能力,还有更多在未来分享喔。这只是我们开始 Pandora.js 之旅的第一部分。

   接下来关于如何守护进程、如何监控应用、如何追踪链路、迷人的 Dashboard、如何与现有 APM 结合(比如 Open-Falcon)都会是一篇篇的干货。大家敬请期待!

   最后,不要忘了给点个 Star 喔~

   https://github.com/midwayjs/pandora

   最后的最后,我们招人。我们有超过一半的淘宝前台访问在 Node.js 上,也有做开源 Node.js 软件的机会,挑战不小,当然回报也不小。

   题图:https://unsplash.com/photos/F9o7u-CnDJk By @Tony Webster

建议继续学习

  1. Oracle MTS模式下 进程地址与会话信息 (阅读 14,187)
  2. Linux内存点滴 用户进程内存空间 (阅读 12,946)
  3. 深入理解Nginx之调试优化技巧 (阅读 8,104)
  4. Linux上进程的表示以及入门 (阅读 7,644)
  5. Linux下进程绑定多CPU运行 (阅读 7,104)
  6. 分析进程内存分配情况,解决程序性能问题 (阅读 6,686)
  7. 什么是Node? (阅读 6,623)
  8. Linux下如何知道文件被那个进程写 (阅读 6,326)
  9. 使用GDB调试多进程程序 (阅读 6,243)
  10. 进程运行于不同的 CPU 核 (阅读 5,825)