中文翻译:
http://www.jinbuguo.com/systemd/systemd.service.html#

系统启动过程
CentOS 7 的启动过程是这样的:

顺序               说明
post               加电
BISO               进入BIOS
bootloader(MBR)    加载磁盘主引导记录
kernel(ramdisk)    加载内核
rootfs             初始化rootfs
/sbin/init         系统初始化。Sysv lnit,Upstart 或 systemd 系统守护进程。
UEFi或BIOS初始化,运行POST开机自检
选择启动设备
引导装载程序, centos7是grub2
加载装载程序的配置文件: /etc/grub.d/
    /etc/default/grub /boot/grub2/grub.cfg
加载initramfs驱动模块
加载内核选项
内核初始化, centos7使用systemd代替init
执行initrd.target所有单元,包括挂载/etc/fstab
从initramfs根文件系统切换到磁盘根目录
systemd执行默认target配置,配置文件
    /etc/systemd/default.target /etc/systemd/system/
systemd执行sysinit.target初始化系统及basic.target准备操
作系统
systemd启动multi-user.target下的本机与服务器服务
systemd执行multi-user.target下的/etc/rc.d/rc.local
Systemd执行multi-user.target下的getty.target及登入服
务
systemd执行graphical需要的服务

Systemd

Systemd 是系统启动和服务器守护进程管理器,负责在系统启动或运行时,激活系统资源,服务器进程和其它进程。
systemd被设计用来改进sysvinit的缺点,它和ubuntu的upstart是竞争对手,预计会取代它们。systemd的很多概念来源于苹果的launchd。创始人Lennart是redhat员工,但systemd不是redhat项目。

systemd的目标是:尽可能启动更少进程;尽可能将更多进程并行启动。systemd尽可能减少对shell脚本的依赖。传统sysvinit使用inittab来决定运行哪些shell脚本,大量使用shell脚本被认为是效率低下无法并行的原因。systemd使用了Linux专属技术,不再顾及POSIX兼容,一度谣传Debian为了它的BSD项目将不会使用systemd。

特性:
系统引导时实现服务并行启动,实现快速开机。
按需启动守护进程。
能自动保存系统状态快照。
基于依赖关系定义服务控制逻辑(自动化的服务依赖关系管理)。
同时采用 socket 式与 D-Bus 总线式激活服务。

核心概念 unit(单元):

一、service unit 常用命令,以 mysql 服务为例

# 开机启动
systemctl enable mysqld
 
# 关闭开机启动
systemctl disable mysqld
 
# 启动服务
systemctl start mysqld
 
# 停止服务
systemctl stop mysqld
 
# 重启服务
systemctl restart mysqld
 
# 查看服务状态
systemctl status mysqld
systemctl is-active sshd.service
 
# 结束服务进程(服务无法停止时)
systemctl kill mysqld

二、服务启动的配置文件

配置文件主要放在 /usr/lib/systemd/system 目录,也可能在 /etc/systemd/system  /lib/systemd/system目录

# 查看 sshd 服务启动文件
systemctl cat sshd.service
 
# /usr/lib/systemd/system/sshd.service
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.service
Wants=sshd-keygen.service
 
[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
 
[Install]
WantedBy=multi-user.target

每个服务文件以 .service 结尾,一般会分为 3 部分,必须包含 [Service] 部分

[Unit] 启动顺序与依赖关系

Description:当前服务的简单描述
Documentation:指定 man 文档位置
 
After:如果 network.target 或 sshd-keygen.service 需要启动,那么 sshd.service 应该在它们之后启动
Before:定义 sshd 应该在哪些服务之前启动
注意:After 和 Before 字段只涉及启动顺序,不涉及依赖关系。
 
Wants:表示 sshd.service 与 sshd-keygen.service 之间存在"弱依赖"关系,即如果"sshd-keygen.service"启动失败或停止运行,不影响 sshd.service 继续执行
Requires:表示"强依赖"关系,即如果该服务启动失败或异常退出,那么sshd.service 也必须退出
注意:Wants 字段与 Requires 字段只涉及依赖关系,与启动顺序无关,默认情况下是同时启动。

[Service] 启动行为

EnvironmentFile:许多软件都有自己的环境参数文件,该字段指定文件路径
注意:/etc/profile 或者 /etc/profile.d/ 这些文件中配置的环境变量仅对通过 pam 登录的用户生效,而 systemd 是不读这些配置的。
systemd 是所有进程的父进程或祖先进程,它的环境变量会被所有的子进程所继承,如果需要给 systemd 配置默认参数可以在 /etc/systemd/system.conf  和 /etc/systemd/user.conf 中设置。
加载优先级 system.conf 最低,可能会被其他的覆盖。
 
 
Type:定义启动类型。可设置:simple,exec,forking,oneshot,dbus,notify,idle
simple(设置了 ExecStart= 但未设置 BusName= 时的默认值):ExecStart 字段启动的进程为该服务的主进程
forking:ExecStart 字段的命令将以 fork() 方式启动,此时父进程将会退出,子进程将成为主进程
 
 
ExecStart:定义启动进程时执行的命令
上面的例子中,启动 sshd 执行的命令是 /usr/sbin/sshd -D $OPTIONS,其中的变量 $OPTIONS 就来自 EnvironmentFile 字段指定的环境参数文件。类似的,还有如下字段:
ExecReload:重启服务时执行的命令
ExecStop:停止服务时执行的命令
ExecStartPre:启动服务之前执行的命令
ExecStartPost:启动服务之后执行的命令
ExecStopPost:停止服务之后执行的命令
 
 
RemainAfterExit:设为yes,表示进程退出以后,服务仍然保持执行
 
 
KillMode:定义 Systemd 如何停止服务,可以设置的值如下:
control-group(默认值):当前控制组里面的所有子进程,都会被杀掉
process:只杀主进程
mixed:主进程将收到 SIGTERM 信号,子进程收到 SIGKILL 信号
none:没有进程会被杀掉,只是执行服务的 stop 命令
 
 
Restart:定义了退出后,Systemd 的重启方式。可以设置的值如下:
no(默认值):退出后不会重启
on-success:只有正常退出时(退出状态码为0),才会重启
on-failure:非正常退出时(退出状态码非0),包括被信号终止和超时,才会重启
on-abnormal:只有被信号终止和超时,才会重启
on-abort:只有在收到没有捕捉到的信号终止时,才会重启
on-watchdog:超时退出,才会重启
always:不管是什么退出原因,总是重启
 
 
RestartSec:表示 Systemd 重启服务之前,需要等待的秒数

配置中多个相同配置会选择最后一个,下面结果是 execstart2

[Service]
ExecStart=/bin/echo execstart1
ExecStart=/bin/echo execstart2

所有的启动设置之前,都可以加上一个连词号(-),表示"抑制错误",即发生错误的时候,不影响其他命令的执行

EnvironmentFile=-/etc/sysconfig/sshd,表示即使/etc/sysconfig/sshd文件不存在,也不会抛出错误

[Install]
WantedBy:表示该服务所在的 Target(服务组)

关于 Target,运行级别

# 查看默认 Target
systemctl get-default
# 结果为 multi-user.target,表示默认的启动 Target 是multi-user.target。在这个组里的所有服务,都将开机启动。这就是为什么 systemctl enable 命令能设置开机启动的原因
 
 
# 查看 multi-user.target 包含的所有服务
systemctl list-dependencies multi-user.target
 
# 切换到另一个 target
# shutdown.target 就是关机状态
# 常用的 Target 有两个:一个是 multi-user.target,表示多用户命令行状态;另一个是 graphical.target,表示图形用户状态,它依赖于 multi-user.target
systemctl isolate shutdown.target

三、自定义开机启动服务的脚本

在 /usr/lib/systemd/system 下新建你需要启动的服务的脚本

vim /usr/lib/systemd/system/zdy.service
 
[Unit]
Description=描述
Environment=环境变量或参数(系统环境变量此时无法使用)
After=network.target
 
[Service]
Type=forking
EnvironmentFile=所需环境变量文件或参数文件
ExecStart=启动命令(需指定全路径)
ExecStop=停止命令(需指定全路径)
User=以什么用户执行命令
 
[Install]
WantedBy=multi-user.target

新建完成后设置自启动

# 添加或修改配置文件后,一定需要重新加载,不然不生效
systemctl daemon-reload
 
# 设置自启动,实质就是在 /etc/systemd/system/multi-user.target.wants/ 添加服务文件的链接
systemctl enable zdy

四、总结一下常用命令

# 需要先重新加载这些变动的文件:
systemctl daemon-reload

# 开机启动
systemctl enable rabbitmq_python.service # or systemctl enable rabbitmq_python

# 还有其他其他命令
systemctl start/restart/stop rabbitmq_python
# 验证一下是否为开机启动:为true表示激活开机启动
systemctl is-enabled rabbitmq_python 
# 重新启动服务
systemctl restart rabbitmq_python 
# 查看所有已启动的服务
systemctl list -units --type=service 
# 停止开机自启动
systemctl disable rabbitmq_python.service 
# 查看服务当前状态
systemctl status rabbitmq_python.service