使用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 系统中,servicesystemctl 命令都可以用来管理当系统服务。

创建服务

这里以一个开源的内网穿透工具 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.targetsyslog.target,表示需要在网络服务和系统日志服务启动之后再启动 FRP。
  • Before:先启动本服务,再启动指定的这些服务,与 After 相反。
  • Requires:依赖的其它服务,列在其中的项会在这个服务启动时同时被启动。并且,如果其中任意一个服务启动失败,这个服务也会被终止。
  • Wants:在启动当前服务时同时启动 Wants 中的其他项。与 Requires 相似,但 Wants 不会管其他的服务是否启动成功。这里指定了 network.target,表示 FRP 启动会同时启动 network.target 服务。
Requires / Wants 与 After/Before 不同,不保证顺序,所以一般需要搭配使用。

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状态

在终端内输入:

systemctl daemon-reload # 重载systemctl
systemctl enable frps   # 在 systemctl 中将 frps 服务状态设为启用
service frps start  # 启动 frps 服务(刚配置好服务需要手动启动一下,或者重启 Linux也行)

这样就成功在 systemctl 中管理刚才创建的服务了。

通过 service frps status 可以看到相关的运行信息,不出意外的话服务应该处于活动(active)状态。

启用systemctl服务

最下方显示的是标准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),获取干货推送
THE END
分享
二维码
< <上一篇
下一篇>>
文章目录
关闭
目 录