[译] 在生产环境运行 PM2 & Node.js

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: [译] 在生产环境运行 PM2 & Node.js

原文:medium.com/hackernoon/…

维护你的代码库并保持其相关性确有难度;但与之相比我们会发现,维护一个应用时最大的挑战来自于保持其存活和运行。不仅如此,随着 Node.js 变成大部分后端 API 的核心语言,单线程程序的伸缩也变得困难;这就是 PM2 出现并受到欢迎的原因了。

有很多进程管理工具,广为人知的如 Foreverstrong-pm,或是不错的 Linux 系统工具 SystemD。还有就是本文的主角 PM2,有着 4100 多万的总下载量和 31k GitHub stars(译注:截止本文翻译时)。究其原因,简单地说,就是其简单易用并且让管理一个生产环境变得天衣无缝。

何为 PM2?

正如其新版首页中所标榜的,PM2 是一个“身经百战(battle hardened)”的、适用于生产环境的 Node.js 应用运行时和进程管理工具。 也自带了内建的 负载均衡器,这使得扩展应用愈加容易。最棒的是,它在 Linux、Windows 和 macOS 都能工作。

通过一个 process.json 配置文件(译注:该文件可自行命名,一般叫做 process.json、processes.json 或 ecosystem.json,该名称将作为参数传入 pm2 start 等命令中),你可以指定想要运行的进程及要扩展到多少个进程。当启动 PM2 时,它将根据以上配置文件处理其他所有的事情(甚至比配置文件指定的更多一些 😉)。

所有这些意味着 PM2 能帮助你保持 Node.js 应用永远运行下去,并在你更新应用或服务器时以 0 故障停机时间自动重启。

安装 PM2

安装 PM2 就是小菜一碟。首先,确保你已经配置好了 process.json 文件,用以启动进程。

一般只需运行 yarn add global pm2 即可安装。如果使用了一个 Docker 容器(对,也支持 Docker),按照 pm2.keymetrics.io/docs/usage/… 中的说明安装。

如果你实在好奇它看起来长什么样,这里有一个 process_prod.json 文件的例子,用于一个开源的 RSS & 播客 应用:

// process_prod.json
{
  "apps": [{
      "name": "api",
      "cwd": "api/dist",
      "script": "server.js",
      "watch": false
    },
    {
      "name": "conductor",
      "cwd": "api/dist/workers",
      "script": "conductor.js",
      "watch": false
    },
    {
      "name": "rss-worker",
      "cwd": "api/dist/workers",
      "script": "rss.js",
      "instances": 2,
      "exec_mode": "cluster",
      "watch": false
    },
    {
      "name": "podcast-worker",
      "cwd": "api/dist/workers",
      "script": "podcast.js",
      "instances": 2,
      "exec_mode": "cluster",
      "watch": false
    },
    {
      "name": "og-worker", // 应用名称
      "cwd": "api/dist/workers", // 启动应用的目录
      "script": "og.js", // 启动脚本
      "instances": 2, // 被启动的应用实例数量
      "exec_mode": "cluster", // 启动模式,默认为 fork
      "watch": false, // 如果允许 watch,则其中的文件改变会引发重启
      "max_memory_restart": "150M" // 引发重启的最大内存使用量
    }
  ]
}

如你所见,我们运行了若干个进程,并且 PM2 轻松掌控了一切;其自动地使用了 Node.js 的 Cluster API 以实现多进程。

译注:配置文件的完整介绍见 pm2.keymetrics.io/docs/usage/…

技巧 & 经验

对于任何应用(或者本例中的进程管理工具),从先行者那里了解一些技巧和经验都是有好处的。

自动重启

一旦 PM2 启动,你的应用就将永远存活,并在应用崩溃和机器重新启动后自动重启 -- 所有这些只消一条简单的命令(用于获得针对所在机器的自动配置过的启动脚本):

pm2 startup

如:

$ pm2 startup
[PM2] You have to run this command as root. Execute the following command:
      sudo su -c "env PATH=$PATH:/home/unitech/.nvm/versions/node/v4.3/bin pm2 startup <distribution> -u <user> --hp <home-path>

只要按照打印的结果,拷贝并运行得到的脚本就行了。

进程管理

不管你运行了多少个应用,PM2 的一套命令都能让你管理它们各自的状态。以下是常用的一些命令(不区分顺序):

  • pm2 start process_prod.json — 通过进程配置文件启动进程
  • pm2 ls — 列出所有的应用
  • pm2 stop <app> — 停止指定的应用
  • pm2 start <app> — 启动指定的应用
  • pm2 <app> scale N — 缩放指定应用的实例数量
  • pm2 kill — 杀掉所有运行中的应用
  • pm2 restart — 重启所有运行中的应用
  • pm2 reload — 重新加载应用配置(这会在你修改了应用的环境变量时派上用场)

进程监控

运行命令 pm2 monit 会返回关于应用健康的丰富数据。比如,你将看到 CPU 利用率、内存使用量、请求分钟数等等。

日志管理

PM2 内建了日志管理功能。它从所有你的应用中聚合日志数据,并将其写入一个用于阅读的源文件中。你甚至可以通过事实跟踪日志来看到应用背后正在发生什么。 PM2 的日志管理也提供了日志循环,这一点非常重要,特别是当应用程序频繁地输出详细日志时。

有三条我经常使用的命令,想必你也应该一样:

  • pm2 logs — 从所有正在运行的应用中输出日志
  • pm2 logs <app> — 只从指定的应用中输出日志
  • pm2 flush — 刷新所有日志数据,释放磁盘空间

请记住,确保日志循环是最重要的事情。这样做将会把一个巨大的日志文件分割成若干易于 PM2 管理的小文件。要做到这点,运行如下命令:

pm2 install pm2\-logrotate

日志管理的更多信息可以在 pm2.keymetrics.io/docs/usage/… 找到。

如果发现你的实例经常被日志填满,也可以考虑使用一个集中式日志服务,如  LogglyPapertrail,或 ELK

最佳实践

通常,我会乐于遵守 “应用十二因素”(12factor.net/)所述的实践。这将帮助… PM2 所有的优势。如果你已经阅读过其声明,应该见到了这 12 条规则:

  1. 一个置于版本控制下的代码库, 多份部署
  2. 明确地声明,并隔离依赖
  3. 在环境而非代码中存储配置
  4. 将后端服务视为附加资源
  5. 严格区分构建和运行阶段
  6. 以一个或多个无状态进程运行应用
  7. 通过端口绑定输出服务
  8. 通过进程模型扩展
  9. 通过快速启动和优雅地关闭保证最大的健壮性
  10. 尽可能保持开发和线上环境尽量一致
  11. 把日志视为事件流
  12. 以一次性进程的形式运行后台管理任务

如果遵守了以上规则,你将能够通过 PM2 高效而安全地扩展任何应用。


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
10天前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
|
1月前
|
JavaScript
webpack学习五:webpack的配置文件webpack.config.js分离,分离成开发环境配置文件和生产环境配置文件
这篇文章介绍了如何将webpack的配置文件分离成开发环境和生产环境的配置文件,以提高打包效率。
46 1
webpack学习五:webpack的配置文件webpack.config.js分离,分离成开发环境配置文件和生产环境配置文件
|
2月前
|
前端开发 JavaScript Java
JavaScript的运行原理
JavaScript 的运行原理包括代码输入、解析、编译、执行、内存管理和与浏览器交互几个步骤。当打开网页时,浏览器加载 HTML、CSS 和 JavaScript 文件,并通过 JavaScript 引擎将其解析为抽象语法树(AST)。接着,引擎将 AST 编译成字节码或机器码,并在执行阶段利用事件循环机制处理异步操作,确保单线程的 JavaScript 能够高效运行。同时,JavaScript 引擎还负责内存管理和垃圾回收,以减少内存泄漏。通过与 DOM 的交互,JavaScript 实现了动态网页效果,提供了灵活且高效的开发体验。
|
3月前
|
C# 开发者 测试技术
震惊!Xamarin 竟能如此构建跨平台应用程序,代码共享、界面设计与性能优化全攻略大揭秘!
【8月更文挑战第31天】在移动应用开发领域,跨平台工具日益受到青睐。Xamarin 是一款强大的工具,支持使用 C# 开发适用于 iOS、Android 和 Windows 的应用。通过安装 Visual Studio 或 Visual Studio for Mac,并创建 Xamarin 项目,开发者可以利用丰富的功能和工具进行开发。Xamarin 的主要优势在于代码共享,能够显著提高开发效率。
69 0
|
3月前
|
JavaScript 前端开发 应用服务中间件
Vue.js项目部署与优化:一场从本地到生产环境的华丽蜕变,见证你的应用如何凤凰涅槃,惊艳上线!
【8月更文挑战第30天】作为一名前端开发者,掌握从本地开发环境到生产环境的迁移至关重要。本文将带你了解如何使用 Vue.js 构建和打包应用,确保其在生产环境中流畅运行。首先,通过 `npm run build` 或 `yarn build` 命令生成生产环境文件;接着,配置服务器(如 Nginx)以支持静态文件服务;最后,通过代码分割、资源压缩、CDN 使用、服务端渲染及缓存策略等手段优化应用性能。跟随本文,你将学会如何让 Vue.js 应用在真实环境中表现优异,为用户提供流畅体验。
52 0
|
3月前
|
JavaScript 应用服务中间件 测试技术
[译] 为何要对生产环境的 Node.js 使用反向代理?
[译] 为何要对生产环境的 Node.js 使用反向代理?
|
3月前
|
JavaScript Windows
【Azure 应用服务】用App Service部署运行 Vue.js 编写的项目,应该怎么部署运行呢?
【Azure 应用服务】用App Service部署运行 Vue.js 编写的项目,应该怎么部署运行呢?
|
3月前
|
JavaScript 前端开发 C++
【Azure Function】调试 VS Code Javascript Function本地不能运行,报错 Value cannot be null. (Parameter 'provider')问题
【Azure Function】调试 VS Code Javascript Function本地不能运行,报错 Value cannot be null. (Parameter 'provider')问题
|
4月前
|
存储 JavaScript 安全
Node中的AsyncLocalStorage 使用问题之生产环境中使用async_hooks的问题如何解决
Node中的AsyncLocalStorage 使用问题之生产环境中使用async_hooks的问题如何解决
|
3月前
|
Kubernetes 容器 Perl
Kubernetes(K8S) Node NotReady 节点资源不足 Pod无法运行
Kubernetes(K8S) Node NotReady 节点资源不足 Pod无法运行
69 0