今看摇落,凄怆江潭:树犹如此,人何以堪?——姜夔《长亭怨慢·渐吹尽》
1.背景
在linux上开发时,往往需要将自己的程序做成服务,并且实现服务开机自动重启,以及服务崩溃后自动重启功能,本文就对该功能的实现做简单介绍,实现方法很简单,使用linux系统的systemd即可实现
2. systemd介绍
历史上,linux的启动一直采用init进程,比如
sudo /etc/init.d/apache2 start
# 或者
service apache2 start
这种方法有两个缺点。
- 一是启动时间长。init进程是串行启动,只有前一个进程启动完,才会启动下一个进程。
- 二是启动脚本复杂。init进程只是执行启动脚本,不管其他事情。脚本需要自己处理各种情况,这往往使得脚本变得很长。
Systemd 就是为了解决这些问题而诞生的。它的设计目标是,为系统的启动和管理提供一套完整的解决方案。根据 Linux 惯例,字母d是守护进程(daemon)的缩写。 Systemd 这个名字的含义,就是它要守护整个系统。使用了 Systemd,就不需要再用init了。Systemd 取代了initd,成为系统的第一个进程(PID 等于 1),其他进程都是它的子进程。
systemctl是 Systemd 的主命令,用于管理系统。对于用户来说,最常用的是下面这些命令,用于启动和停止 Unit(主要是 service)。
# 立即启动一个服务
sudo systemctl start apache.service
# 立即停止一个服务
sudo systemctl stop apache.service
# 重启一个服务
sudo systemctl restart apache.service
# 杀死一个服务的所有子进程
sudo systemctl kill apache.service
# 重新加载一个服务的配置文件
$ sudo systemctl reload apache.service
# 重载所有修改过的配置文件
sudo systemctl daemon-reload
# 显示某个 Unit 的所有底层参数
systemctl show httpd.service
# 显示某个 Unit 的指定属性的值
systemctl show -p CPUShares httpd.service
# 设置某个 Unit 的指定属性
sudo systemctl set-property httpd.service CPUShares=500
本文主要是对systemd的使用进行介绍,如果想进一步了解systemd的基本知识,可查阅相关资料
2.创建服务
[Unit]
Description=Pose Service
After=network.target
[Service]
Type=simple
ExecStart=/bin/bash -c "cd /home/nvidia/detection/detect/bin/workspace && ./example"
[Install]
WantedBy=multi-user.target
这个unit文件在服务启动时会执行/bin/bash -c命令,该命令将切换到/home/nvidia/detection/detect/bin/workspace目录并运行./example可执行文件。请注意,这里使用-c选项是为了告诉bash将整个命令作为字符串解析,因此可以包含多个命令和操作符。
有几点需要注意,为了使服务能够自动无限次重启,需要增加以下几个配置
StartLimitIntervalSec=0
Restart=always
RestartSec=1
关于配置文件的具体参数含义,可参考该文档
如果要设置环境变量,则需要在Service中添加Environment,比如
Environment=PYTHONPATH=$PYTHONPATH:/root/robot/models-master/research/:/root/robot/models-master/research/slim
3. 常用命令
请确保将此文件保存为pose.service并将其放置在/etc/systemd/system/目录中,然后使用以下命令启动服务:
sudo systemctl start pose
sudo systemctl stop pose
如果您需要在系统启动时自动启动服务,可以使用以下命令启用自动启动:
sudo systemctl enable pose
也可以使用
sudo service pose (status/ start / restart /stop)
可以使用 journalctl 工具查看指定服务的输出,使用 -u 指定服务名称,使用 -f 可以实时输出
sudo journalctl -n -f -u baoshen.service
-n 表示 返回最新的日志
-f 表示 持续显示最新的日志,类似 tail -f
-u 表示只显示哪个service的日志
-r 反向倒序输出
4. 普通用户服务
上边介绍的服务默认是用 root 权限执行,如果要创建普通用户的服务,方法如下
cd ~/.config
mkdir systemd && cd systemd
mkdir user && cd user
touch test.service
按照上边的格式写一个服务的内容,启动的方法是
systemctl --user daemon-reload
systemctl --user start test.service
其它命令与 root 的类似,只需要加 --user 关键字即可