systemd 是目前大部分 Linux 发行版带有的系统守护进程。它能实现诸多系统操作,其中一项就是管理系统服务,能更好地解决启动先后顺序等进程需求。一些发行版(比如 Debian)把 rc.local 的开机启动都直接当作一项服务,而 Arch Linux 甚至默认不自带 rc.local,一切开机自启基本都通过 systemd 来实现。

因此还在偷懒只写开机启动脚本的童鞋们,快来弃暗投明写systemd 吧(迫真

systemd 服务的特性

  • 能实现不同服务间的依赖关系,处理先后次序
  • 能指定以某用户的权限执行
  • 自动托管为守护进程,输出可以自动被系统记录成日志
  • 不但能自启,还可以定义关闭重启、重新加载配置文件等操作
  • 相对于较早期的 init.d 脚本写起来更简短清晰,并有一定的规范

使用方法

编写服务文件

对于用户服务,文件一般放在 /etc/systemd/system 下,拓展名为 .service

1
$ sudo touch /etc/systemd/system/<name>.service

服务文件的具体写法在下面会具体讲到,我们就先假设这个服务已经写好了。

重载服务文件

为了使作出的修改生效,我们需要执行:

1
$ sudo systemctl daemon-reload

对服务的操作

通用命令为:sudo systemctl <opt> <name>.service,常见操作如下:

开机自启enable取消开机自启disable
启动start关闭stop
重启restart重新加载配置reload
查看状态status

简单的服务模板

这里介绍一些最基本的配置,反正对我来说是够用了。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
[Unit]
Description=the app as a sample
After=network.target network-online.target nss-lookup.target

[Service]
Type=simple
User=nobody
WorkingDirectory=/opt/sample
ExecStartPre=sleep 5
ExecStart=/opt/sample/xxx run
ExecStartPost=echo "done"
ExecReload=/opt/sample reload
KillSignal=SIGQUIT
KillMode=mixed
Restart=on-failure

[Install]
WantedBy=multi-user.target

这就是一个非常简单模板,这里不会深究原理,主要会举例说明这些选项的作用。通过修改这个模板来对付日常需求应该足矣。一些太易懂或者不需要改直接抄就行的内容就跳过不做解释了。

  • After 部分是指启动顺序,一般像上面那样就是表示网络服务启动了。如果想在某服务后启动,就在后面接着写服务名,比如 nginx.service 等。
  • Type 是服务启动类型,simple 表示当作一个简单的程序运行。就是那种启动后挂在那里,并会进行一些输出之类的程序。systemd 会把他它在后台 ,把输出放到日志里,非常方便。此外还有别的启动方式,见后面章节的补充。
  • User 是服务运行时的用户权限。
  • WorkingDirectory 时服务的上下文路径。
  • ExecStartPre 是在服务进程开始前的运行内容,可以用来进行环境配置或准备工作。
  • ExecStart 是启动服务的运行命令。
  • ExecReload 是重新加载配置的命令。
  • KillSignal 是服务在终止时给主进程发出的 kill 信号,一般来说不需要特别指出。
  • KillMode 是终止服务时所执行的流程,mixed 能胜任大部分情形。
  • Restart 是重启服务条件,on-failure 是启动失败时尝试重启,同样也是推荐配置。

补充

  • 对于本身就以后台程序运行的执行文件,或是想要运行多个进程的服务,Type 可选用 forkingExecStart 当作主进程。此时主进程所拉起的其他进程都会被被纳入服务中,且并行执行。这种情况下最好写一个 ExecStop,使停止服务时能完全关闭各个进程。不过实际使用中发现 mixedKillMode 能比较彻底地清理服务涉及到的所有进程。

样例

Simple 类型 - Apache Tomcat

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[Unit]
Description=Apache Tomcat
After=network.target network-online.target nginx.service

[Service]
Type=simple
User=http
WorkingDirectory=/opt/apache-tomcat/bin
ExecStart=/opt/apache-tomcat/bin/catalina.sh run

[Install]
WantedBy=multi-user.target

Forking 类型 - aria2

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
[Unit]
Description=aria2 with RPC
After=network.target network-online.target nss-lookup.target

[Service]
Type=forking
User=alice
WorkingDirectory=/home/alice
ExecStart=/usr/bin/aria2c --conf-path /home/alice/.aria2/aria2.conf -D
ExecStop=killall aria2c
Restart=on-failure
KillMode=mixed

[Install]
WantedBy=multi-user.target