Node 应用的 Systemd 启动

前面的文章介绍了 Systemd 的操作命令基本用法,今天给出一个实例,如何使用 Systemd 启动一个 Node 应用。

本文是独立的,不需要前面的教程作为预备知识。


一、克隆代码

首先,下载示例库


$ git clone https://github.com/ruanyf/node-systemd-demo.git
$ cd node-systemd-demo

示例脚本server.js非常简单,就是一个 HTTP 服务器。

 var http = require('http'); var hostname = '0.0.0.0'; var port = 5000;

http.createServer(function(req, res) {
 res.writeHead(200, {'Content-Type': 'text/plain'});
 res.end('Hello World'); }).listen(port, hostname, function () {
 console.log('Server running at http://%s:%s/', hostname, port); }); 

二、修改配置文件

Systemd 启动上面这个脚本,需要一个配置文件node-server.service。这个文件的文件名可以随便取,但是后缀名必须是.service

 [Unit]
Description=node simple server

[Service]
ExecStart=[/path/to/node/executable] [path/to/node-systemd-demo]/server.js
Restart=always
User=[yourUserName]
Group=[yourUserGroup]
Environment=PATH=/usr/bin:/usr/local/bin
Environment=NODE_ENV=production
WorkingDirectory=[/path/to/node-systemd-demo] [Install]
WantedBy=multi-user.target

上面脚本里面,有五个地方出现了四个占位符。

  • [/path/to/node/executable]:node可执行文件的绝对路径
  • [path/to/node-systemd-demo]:示例库的绝对路径
  • [yourUserName]:你的用户名
  • [yourUserGroup]:你的组名

你需要将上面这四个占位符,改成自己电脑的设置。下面是一个已经改好的例子。

 [Unit]
Description=node simple server

[Service]
ExecStart=/usr/bin/node /tmp/node-systemd-demo/server.js
Restart=always
User=nobody
Group=nobody
Environment=PATH=/usr/bin:/usr/local/bin
Environment=NODE_ENV=production
WorkingDirectory=/tmp/node-systemd-demo

[Install]
WantedBy=multi-user.target

如果你不知道这几个占位符的值,下面的命令可以帮你找出来。

 # node executable path
$ which node

# your user name
$ id -un

# your group name
$ id -gn

三、配置文件的解释

简单解释一下,上面的配置文件的几个参数。

Unit区块的Description字段,是服务的简单描述。

Service区块的字段含义如下。

  • ExecStart:启动命令
  • Restart:如何重启。always表示如果进程退出,总是重启
  • Environment:环境变量
  • WorkingDirectory:工作目录

Install区块的WantedBy字段指定,设为开机启动时,该服务所在的 Target 是multi-user.target

四、启动服务

现在将配置文件拷贝到 Systemd 之中。


$ sudo cp node-server.service /etc/systemd/system

接着,就启动服务。

 # 重载配置文件
$ sudo systemctl daemon-reload

# 启动服务
$ sudo systemctl start node-server

访问 http://0.0.0.0:5000,应该看到网页显示"Hello World"。

五、查看状态

如果启动失败,或者想查看日志,就要执行下面的命令。

 # 查看状态
$ sudo systemctl status node-server

# 查看日志
$ sudo journalctl -u node-server

# 实时输出最新日志
$ sudo journalctl --follow -u node-server

六、重启服务和停止服务

 # 重启服务
$ sudo systemctl restart node-server

# 停止服务
$ sudo systemctl stop node-server

如果想设为开机启动,就要执行systemctl enable


$ sudo systemctl enable node-server

七、Socket 激活

一般情况下,学到这里,应该就够用了。如果你还想体验一下 Systemd 的强大功能,请接着往下读。

我们知道,HTTP服务器启动在那里,终究是耗费资源的。那么能不能做到,只有有人访问时,才启动服务,否则就关闭?

这在 Systemd 里面叫做"Socket 激活"。开发者可以指定 Socket 监听的端口,系统根据有没有收到请求,自动启动或关闭服务。不难想到,只要前面加一层负载均衡器,这就等同于实现了一个简单的云服务,即根据访问量,系统自动扩容或收缩。

下面就是"Socket 激活"的Demo。

八、安装依赖

首先,请确认前面启动的 Node 服务已经被关闭了,5000 端口已经释放出来了。

然后,打开启动脚本socket-server.js,你会发现多出了两个模块:systemdautoquit

 require('systemd'); require('autoquit'); var http = require('http'); var server = http.createServer(function(req, res) {
 res.writeHead(200, {'Content-Type': 'text/plain'});
 res.end('Hello World'); });

server.autoQuit({ timeOut: 60 });
server.listen('systemd');

console.log('Server running at http://0.0.0.0:5000/'); 

上面代码中,systemd模块用于添加"Socket 激活",autoquit模块用于指定多少时间无人访问后,关闭 Node 服务,上面脚本是60秒。另外,还有一个journald模块,用于向 Systemd 日志添加内容,这个例子中没有使用。

现在,安装依赖。


$ npm install

九、改写配置文件

Socket 激活需要两个配置文件。

一个是node-socket-server.socket

 [Socket]
ListenStream=5000 [Install]
WantedBy=sockets.target

另一个是node-socket-server.service

 [Unit]
Description=node simple server (socket activation) [Service]
ExecStart=[/path/to/node/executable] [path/to/node-systemd-demo]/socket-server.js
User=[yourUserName]
Group=[yourGroupName]
Environment=PATH=/usr/bin:/usr/local/bin
Environment=NODE_ENV=production
WorkingDirectory=[/path/to/node-systemd-demo] 

上面这个文件需要改写占位符。可以看到,由于不是开机启动,配置文件里面没有Install区块;由于不需要重启,也没有Restart字段。

改写后,将它们拷贝到 Systemd。


$ sudo cp node-socket-server.socket /etc/systemd/system
$ sudo cp node-socket-server.service /etc/systemd/system

十、启动 Socket 激活

然后,执行下面两个命令,启动 Socket 激活。


$ sudo systemctl daemon-reload
$ sudo systemctl start node-socket-server.socket

这个时候,检查一下状态。


$ sudo systemctl status node-socket-server.socket
● node-socket-server.socket
 Loaded: loaded (/etc/systemd/system/node-socket-server.socket; disabled)
 Active: active (listening) since 2016-03-10 20:36:41 CST; 7s ago
 Listen: [::]:5000 (Stream)

$ sudo systemctl status node-socket-server.service
● node-socket-server.service - node simple server (socket activation)
 Loaded: loaded (/etc/systemd/system/node-socket-server.service; disabled)
 Active: inactive (dead) 

可以看到,node-socket-server.socket是激活的(active),而node-socket-server.service没有(inactive)。

这时访问 http://0.0.0.0:5000 ,会发现网页可以正常访问。

然后,再检查一下状态。


$ sudo systemctl status node-socket-server.socket
● node-socket-server.socket
 Loaded: loaded (/etc/systemd/system/node-socket-server.socket; disabled)
 Active: active (running) since 2016-03-10 20:36:41 CST; 1min 20s ago
 Listen: [::]:5000 (Stream)

$ sudo systemctl status node-socket-server.service
● node-socket-server.service - node simple server (socket activation)
 Loaded: loaded (/etc/systemd/system/node-socket-server.service; disabled)
 Active: active (running) since 2016-03-10 20:37:55 CST; 3min 11s ago
 Main PID: 1084 (node)
 CGroup: /system.slice/node-socket-server.service
 └─1084 node /home/ruanyf/project/node-systemd-demo/socket-server.js

这时,socketservice都激活了。

十一、停止服务

此时,如果手动停止 HTTP 服务器,Systemd 会发出一个警告。


$ sudo systemctl stop node-socket-server.service
Warning: Stopping node-socket-server.service, but it can still be activated by:
 node-socket-server.socket

上面的警告表示,Socket 依然是激活的,因此服务随时可能被重启,所以还需要关闭 Socket 激活。


$ sudo systemctl stop node-socket-server.socket

十二、参考链接

(完)

时间: 2024-09-02 16:00:48

Node 应用的 Systemd 启动的相关文章

走进Linux之systemd启动过程

走进Linux之systemd启动过程 Linux系统的启动方式有点复杂,而且总是有需要优化的地方.传统的Linux系统启动过程主要由著名的init进程(也被称为SysV init启动系统)处理,而基于init的启动系统被认为有效率不足的问题,systemd是Linux系统机器的另一种启动方式,宣称弥补了以传统Linux SysV init为基础的系统的缺点.在这里我们将着重讨论systemd的特性和争议,但是为了更好地理解它,也会看一下通过传统的以SysV init为基础的系统的Linux启动

node js-webstorm 无法Debug启动

问题描述 webstorm 无法Debug启动 Debugger listening on port 60916Running ""concurrent:debug"" (concurrent) taskError: listen EADDRINUSE at exports._errnoException (util.js:746:11) at Agent.Server._listen2 (net.js:1129:14) at listen (net.js:1155

使用systemd管理Node.js应用

systemctl systemctl是查询和控制systemd的主要命令,下面以mongod为例介绍常用参数: MongoDB是Node.js下非常常见的NoSQL数据库,在ArchLinux下通过pacman安装:pacman install mongodb,安装成功后mongod即为可用的systemd服务. # 查看服务状态 systemctl status mongod # 启动服务 systemctl start mongod # 停止服务 systemctl stop mongod

《深入浅出Node.js》作者分享:Node.js应用性能监控与问题诊断

直播回顾视频:https://yq.aliyun.com/edu/lesson/play/333 以下内容是根据直播和PPT整理. Node.js的优势与劣势 Node.js是基于JavaScript编写而成的强大的Web开发框架,它易于上手.入门简单:同时ECMAScript新规范.特性更新活跃,按年为单位进行更新.得益于弱类型语言的特性,Node.js的开发效率奇高,通过使用事件驱动.非阻塞式 I/O 的模型,使其轻量又高效.Node.js特别适合于web应用或API服务器,例如手机上的AP

Node.js入门学习笔记

关于Node.js介绍,我们引用官网(http://nodejs.org/)的一段文字说明: 1 Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and ef

PHP vs Node.js 深入讨论

网络正在处于一个日新月异的发展时代.服务器端开发人员在选择语言的时候非常困惑,有长期占主导地位的语言,例如C.Java和Perl,也有专注于web开发的语言,例如Ruby.Clojure和Go.只要你的项目运行良好,你的选择就显得没有那么重要了. 但是如何让这些新的web开发人员做出一个正确的选择呢? 我不希望展开一场PHP.NodeJs两大阵营之间的战争,我将会对比这两种语言所在领域的发展状况: PHP Rasmus Lerdorf在1994年创造出了PHP.它是由安装在web服务器(Apac

Linux基础命令介绍十三:启动流程

固件(firmware)是指设备最底层的,让设备得以运行的程序代码.简单理解就是:固定在硬件上的软件.计算机中的许多设备都拥有固件(如硬盘.鼠标.光驱.U盘等),在计算机启动过程中,最先读取的就是位于主板上的固件,这个固件当前有两种类型:传统的BIOS和新的通用性更强的UEFI. 在上一篇中,我们提到另一种磁盘分区格式GTP也是UEFI标准的一部分.于是,当前计算机启动中,出现了两种不同的方式:BIOS/MBR和UEFI/GTP. 在linux操作系统的世界中,同样在经历着变革,系统初始化软件s

使用Node.js、Express、MongoDB和AngularJS构建问卷调查应用程序

在前端,该应用程序会使用 AngularJS 和 Bootstrap 支持用户界面,并使用 Web Sockets 来支持投票,以便实时更新客户端. 最近,在向大学生们介绍 HTML5 的时候,我想要对他们进行问卷调查,并向他们显示实时更新的投票结果.鉴于此目的,我决定快速构建一个用于此目的的问卷调查应用程序.我想要一个简单的架构,不需要太多不同的语言和框架.因此,我决定对所有一切都使用 JavaScript - 对服务器端使用 Node.js 和 Express,对数据库使用 MongoDB,

Node.js进程管理之Process模块

在前面Node.js事件运行机制也有提到,Node.js应用在单个线程运行,但是现在大部分服务器都是多处理器,为了方便使用多个进程,Node.js提供了3个模块.Process模块提供了访问正在运行的进程.child_process模块可以创建子进程,并与他们通信.cluster模块提供了实现共享相同端口的集群服务能力,允许多个请求同时处理. 一.Process模块是一个无须使用require()就可以从node.js应用程序进行访问的全局对象. 二.进程I/O管道 Process为进程stdi