最近在服务器上部署程序的时候,接到一个重启之后能自动启动所有服务的需求。这个操作居然不会,之前重启之后都是手动启动服务的,于是赶紧学习并记录一下。详细教程请参考http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html
设置开机启动有两种方式:一种是在/etc/init.d/目录下增加程序控制的脚本,然后使用chkconfig命令设置服务开机启动。另一种是使用Systemd。
前一种方式依赖Linux的init进程,因为各种缺陷,现在慢慢被Systemd所代替。
Systemd的设计目标是,为系统的启动和管理提供一套完整的解决方案。
Systemd将管理的系统资源统称为Unit。Unit一共分为12种:
1 | Service unit:系统服务 |
其中对于管理我们自己的服务来说,使用的Service unit。
Unit配置文件
Systemd默认从目录/etc/systemd/system中读取Unit的配置文件。
Unit配置文件分为3个区块。
[Unit]区块通常是配置文件的第一个区块,用来定义Unit的元数据,以及配置与其他Unit的关系。它的主要字段如下:
1 | Description:简短描述 |
[Install]通常是配置文件的最后一个区块,用来定义如何启动,以及是否开机启动。它的主要字段如下:
1 | WantedBy:它的值是一个或多个 Target,当前 Unit 激活时(enable)符号链接会放入/etc/systemd/system目录下面以 Target 名 + .wants后缀构成的子目录中 |
[Service]区块用来Service的配置,只有Service类型的Unit才有这个区块。它的主要字段如下:
1 | Type:定义启动时的进程行为。它有以下几种值。 |
Unit配置示例
下面是一个最简单的Unit配置:
1 | [Unit] |
当我们执行sudo systemctl start demo.service启动demo服务时,就会执行/usr/bin/python3 -m http.server 8111启动一个http服务。
现在,执行以下命令就可以实现demo服务的开机启动:
1 | sudo systemctl enable demo.service |
重启之后,执行sudo systemctl status demo.service查看demo服务的状态:

我们发现demo服务已经在运行了。
上面的输出结果含义如下:
1 | Loaded行:配置文件的位置,是否设为开机启动 |
Unit示例配置说明:
[Unit]区块,表示启动顺序与依赖关系。
After字段表示:如果network.target需要启动,那么demo.service应该在他们之后启动。相应还有一个Before字段,定义demo.service应该在哪些服务之前启动。
Requires字段表示”强依赖”关系,即如果network.target服务启动失败或异常退出,那么demo.service也必须退出。相应还有一个Wants字段,表示network.target和demo.service之间存在”弱依赖”关系,即如果network.target启动失败或停止运行,不影响demo.service继续运行。
[Service]区块,定义如何启动当前服务。
ExecStart字段:定义启动进程时执行的命令。与之作用相似的还有如下字段:
1 | ExecReload字段:重启服务时执行的命令 |
Type字段定义启动类型。它可以设置的值如下:
1 | simple(默认值):ExecStart字段启动的进程为主进程 |
KillMode字段:定义了Systemd如何停止sshd服务。可以设置的值如下:
1 | control-group(默认值):当前控制组里面的所有子进程,都会被杀掉 |
Restart字段:定义了服务退出后,Systemd的重启方式。可以设置的值如下:
1 | no(默认值):退出后不会重启 |
RestartSec字段:表示Systemd重启服务之前,需要等待的秒数。
[Install]区块:定义如何安装这个配置文件,即怎样做到开机启动。
WantedBy字段,表示该服务所在的Target。
Target的含义是服务组,表示一组服务。WantedBy=multi-user.target指的是,demo服务所在的Target是multi-user.target。
这个设置非常重要,因为执行systemctl enable demo.service命令时,demo.service的一个符号链接,会放在/etc/systemd/system目录下面的multi-user.target.wants子目录中:

Systemd默认启动的Target是graphical.target

在graphical.target组里的所有服务,都将开机启动。而multi-user.target包含在graphical.target中:

因此demo.service就会随着multi-user.target开机启动。
修改配置文件后,需要执行sudo systemctl daemon-reload命令重新加载配置文件。
几个真实Unit配置示例
zookeeper
1 | [Unit] |
kafka
1 | [Unit] |
elasticsearch
1 | [Unit] |
http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html
http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-part-two.html
https://blog.csdn.net/lineuman/article/details/52578399