【转载】使用 systemd 管理 Node.js 应用
systemd 是 Linux 下的一款系统和服务管理器,该软件的初衷是提供精确的服务间依赖,以此支持并行启动来提高性能。越来越多的 Linux 发行版都由 sysvinit 迁移到了 systemd(包括 Debian!)。在这些 Linux 系统中,用原生的 systemd 来托管 Node.js 进程足够满足一般开发者的要求,借由 systemd 可以很方便地处理依赖关系和监测日志。
systemctl
systemctl
是查询和控制 systemd 的主要命令,下面以 mongod
为例介绍常用参数:
MongoDB 是 Node.js 下非常常见的 NoSQL 数据库,在 ArchLinux 下通过 pacman 安装:
pacman install mongodb
,安装成功后mongod
即为可用的 systemd 服务。
1 | # 查看服务状态 |
更多信息可查阅 man page:
man systemctl
单元文件
每个 systemd 服务均由一个 单元文件 来定义。这些单元文件位于 /usr/lib/systemd/system/
和 /etc/systemd/system/
,分别存放安装软件包(比如 MongoDB)和系统管理员的单元文件。 systemd 启动时会扫描上述路径并载入相应的单元。
Systemd Unit Files Locations (provided by redhat):
Directory | Description |
---|---|
/usr/lib/systemd/system/ |
Systemd unit files distributed with installed RPM packages. |
/run/systemd/system/ |
Systemd unit files created at run time. This directory takes precedence over the directory with installed service unit files. |
/etc/systemd/system/ |
Systemd unit files created by systemctl enable as well as unit files added for extending a service. This directory takes precedence over the directory with runtime unit files. |
所以在修改或添加单元文件后,需要让 systemd 重新加载扫描并加载这些文件:
1 | sudo systemctl daemon-reload |
单元文件的语法非常简单,类似于 Windows 的 .ini
文件。例如:
1 | [Unit] |
将上述文件保存为 /etc/systemd/system/myapp.service
,运行 systemctl start myapp
即可启动它。通过 systemctl status myapp
来查看状态,通过 journalctl
来查看日志,见下文。
更多信息可查询 man page:
man systemd.unit
监测日志
systemd 采用 cgroups 来监测进程,这意味着 fork 得到的子进程也不会脱离日志。systemd 单元默认的日志输出为 syslog,可通过 journalctl
来查看:
1 | # 指定systemd单元(unit) |
查看实时日志:
1 | journalctl -f |
依赖关系
Node.js 应用通常会依赖于其他的服务,比如 MongoDB、Redis 等。这意味着 myapp 在开机启动时可能会因这些进程未启动而失败。可以在单元文件中指定依赖关系,systemd 便会先启动那些依赖:
1 | [Unit] |
环境与用户组
systemd 支持为每个单元文件设置用户组,以及环境变量。 这在 Node.js 的 Web 应用部署和安全提供了方便。
1 | [Service] |
设置多个环境变量可以编写多条 Environment=
语句,例如:
1 | Environment=PORT=3000 |
用户和组在生产环境下较为有用,用特定的用户来运行 Node.js 应用可以在很大程度上限制网络攻击造成的破坏。