使用systemctl托管linux后台程序
在 Linux 中如果想让一个程序保持在后台运行,一般会使用 nohub
命令,或者是使用 screen
之类的命令创建一个独立的会话来运行。但是如果还想实现一些额外的功能,比如:跟随系统自动启动、进程挂掉后自动重启等,就会比较麻烦了。
还有一种选择是将需要后台运行的程序作为一个 service(服务),交给系统中的 systemctl
组件托管。就像 Nginx、MySQL 等程序一样,不仅可以自动开机启动,而且启动、停止程序也方便了很多。
关于 SYSTEMCTL
systemctl
是 Linux 系统中使用最广泛的系统服务管理命令行工具之一,它是 Systemd init 系统的一部分,用于启动、停止和管理系统服务。
早期版本的 Linux 中并不包含 Systemd,而是使用 service
命令管理系统服务。新的 Linux 操作系统(比如 CentOS 7/Ubuntu 16.04)使用 Systemd 来管理系统服务,因此 systemctl
已经成为管理系统服务的标准方式。但为了向后兼容 Systemd 仍然包含对 service
命令的支持。
因此在现在的 Linux 系统中,service
和 systemctl
命令都可以用来管理当系统服务。
创建服务
这里以一个开源的内网穿透工具 FRP 作为例子,为服务端程序配置一个服务,并保持在后台运行。
每一个服务都有一个对应的配置文件,在系统的 /usr/lib/systemd/system/
目录下,后缀为 .service
。文件名就是服务的名字,在控制服务的的时候会用到。比如 Nginx 的服务名就叫 nginx
,重启服务对应的命令是: service nginx restart
。
理论上服务名可以随便取,不过建议选个简短有意义的名字。这里新建的服务叫 frps
。
创建文件 /usr/lib/systemd/system/frps.service
,文件的内容如下:
[Unit]
Description=frps service
After=network.target syslog.target
Wants=network.target
[Service]
Type=simple
ExecStart=/usr/local/frp/frps -c ./frps.toml
WorkingDirectory=/usr/local/frp
[Install]
WantedBy=multi-user.target
文件中常用可配置的各项解释如下:
Unit 区块
- Description:描述了该服务的信息,一般是用于说明和显示(比如运行
service xxx status
会显示)。 - After:指定这些服务启动后,再启动此服务。这里指定了
network.target
和syslog.target
,表示需要在网络服务和系统日志服务启动之后再启动 FRP。 - Before:先启动本服务,再启动指定的这些服务,与 After 相反。
- Requires:依赖的其它服务,列在其中的项会在这个服务启动时同时被启动。并且,如果其中任意一个服务启动失败,这个服务也会被终止。
- Wants:在启动当前服务时同时启动 Wants 中的其他项。与 Requires 相似,但 Wants 不会管其他的服务是否启动成功。这里指定了
network.target
,表示 FRP 启动会同时启动network.target
服务。
Service 区块
- Type:指定了该服务的类型。一般是
simple
,表示该服务是一个简单的可执行程序。 - ExecStart:指定了启动该服务时要执行的程序路径和参数。按实际填写,程序路径要使用绝对路径。后面的是
-c ./frps.toml
都是传递给程序的启动参数。 - ExecReload:重载当前服务时执行的命令。配置后
service xxx reload
才会有效,不需要可以不写。 - ExecStop:停止当前服务时执行的命令。如果不写,执行
service xxx stop
时会直接停止掉程序。 - WorkingDirectory:指定了该服务的工作目录。如果不需要也可以省略这项。这里是因为在传递给 FRP 的参数中使用了相对路径,所以才设成程序所在目录。
- Environment:为服务指定环境变量
- User:指定运行服务的用户
- Group:指定运行服务的用户组
Install 区块
- WantedBy:指定了该服务的安装位置。这里是
multi-user.target
,表示该服务将被安装到multi-user.target
目标中,即系统的多用户模式下运行,一般不用改。
创建好后,在终端里运行 service frps status
应该就能看到相应的输出了。不过此时服务还未生效,处于未激活(inactive)的状态。
在终端内输入:
systemctl daemon-reload # 重载systemctl
systemctl enable frps # 在 systemctl 中将 frps 服务状态设为启用
service frps start # 启动 frps 服务(刚配置好服务需要手动启动一下,或者重启 Linux也行)
这样就成功在 systemctl 中管理刚才创建的服务了。
通过 service frps status
可以看到相关的运行信息,不出意外的话服务应该处于活动(active)状态。
最下方显示的是标准IO流中的内容(也就是直接在终端中运行程序,程序显示出来的内容)。如果 service 不能正常启动程序,可以根据下面的信息进行排查。
有些系统中,使用 status 查看状态时会进入一个交互模式,此时按方向键是滚动屏幕内容,按 q
退出。
管理服务
配置好服务后,就可以直接通过 service 相关的命令启停程序了。常用的命令如下(其中 xxx
要换成相应服务名):
service xxx start # 启动服务
service xxx stop # 停止服务
service xxx restart # 重启服务(先停止再启动)
service xxx status # 查看指定服务的状态
移除服务
如果需要移除这个服务,与创建服务反向操作即可。还是以 frps
服务为例,终端里运行:
service frps stop # 启动 frps 服务
systemctl disable frps # 在 systemctl 中禁用 frps 服务
systemctl daemon-reload # 重载systemctl
禁用服务后,将对应的文件 /usr/lib/systemd/system/frps.service
删除即可。
https://xyuxf.com/archives/2264
欢迎关注 咸鱼先锋 (微信号公众号:xyuxf),获取干货推送
共有 0 条评论