systemd服务介绍
systemd 是 Linux 下一个与 SysV 和 LSB 初始化脚本兼容的系统和服务管理器。systemd 使用 socket 和 D-Bus 来开启服务,提供基于守护进程的按需启动策略,保留了 Linux cgroups 的进程追踪功能,支持快照和系统状态恢复,维护挂载和自挂载点,实现了各服务间基于从属关系的一个更为精细的逻辑控制,拥有前卫的并行性能。systemd 无需经过任何修改便可以替代 sysvinit
service 文件的构成
service文件一般分为三个部分:[Unit]、[Service]、[Install]
Unit
用来定义 Unit 的元数据,以及配置与其他 Unit 的关系
- Description:简短描述
- Documentation:文档地址
- Requires:当前 Unit 依赖的其他 Unit,如果它们没有运行,当前 Unit 会启动失败
- Wants:与当前 Unit 配合的其他 Unit,如果它们没有运行,当前 Unit 不会启动失败
- BindsTo:与Requires类似,它指定的 Unit 如果退出,会导致当前 Unit 停止运行
- Before:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之后启动
- After:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之前启动
- Conflicts:这里指定的 Unit 不能与当前 Unit 同时运行
- Condition…:当前 Unit 运行必须满足的条件,否则不会运行
- Assert…:当前 Unit 运行必须满足的条件,否则会报启动失败
Service
用来定义Service的配置,只有 Service 类型的 Unit 才有这个部分
-
Type:定义启动时的进程行为。它有以下几种值。
-
Type=simple:默认值,执行ExecStart指定的命令,启动主进程
-
Type=forking:以 fork 方式从父进程创建子进程,创建后父进程会立即退出
-
Type=oneshot:一次性进程,Systemd 会等当前服务退出,再继续往下执行
-
Type=dbus:当前服务通过D-Bus启动
-
Type=notify:当前服务启动完毕,会通知Systemd,再继续往下执行
-
Type=idle:若有其他任务执行完毕,当前服务才会运行
-
-
Type=simple:默认值,执行ExecStart指定的命令,启动主进程
-
Type=forking:以 fork 方式从父进程创建子进程,创建后父进程会立即退出
-
Type=oneshot:一次性进程,Systemd 会等当前服务退出,再继续往下执行
-
Type=dbus:当前服务通过D-Bus启动
-
Type=notify:当前服务启动完毕,会通知Systemd,再继续往下执行
-
Type=idle:若有其他任务执行完毕,当前服务才会运行
-
ExecStart:启动当前服务的命令
-
ExecStartPre:启动当前服务之前执行的命令
-
ExecStartPost:启动当前服务之后执行的命令
-
ExecReload:重启当前服务时执行的命令
-
ExecStop:停止当前服务时执行的命令
-
ExecStopPost:停止当其服务之后执行的命令
-
RestartSec:自动重启当前服务间隔的秒数
-
Restart:定义何种情况 Systemd 会自动重启当前服务,可能的值包括always(总是重启)、on-success、on-failure、on-abnormal、on-abort、on-watchdog
-
TimeoutSec:定义 Systemd 停止当前服务之前等待的秒数
-
Environment:指定环境变量
Install
用来定义如何启动,以及是否开机启动
- WantedBy:它的值是一个或多个 Target,当前 Unit 激活时(enable)符号链接会放入/etc/systemd/system目录下面以 Target 名 + .wants后缀构成的子目录中
- RequiredBy:它的值是一个或多个 Target,当前 Unit 激活时,符号链接会放入/etc/systemd/system目录下面以 Target 名 + .required后缀构成的子目录中
- Alias:当前 Unit 可用于启动的别名
- Also:当前 Unit 激活(enable)时,会被同时激活的其他 Unit
自动启动
对于那些支持 Systemd 的软件,安装的时候,会自动在/usr/lib/systemd/system目录添加一个配置文件,如: systemctl enable httpd.service
上面的命令相当于在 /etc/systemd/system 目录添加一个符号链接,指向 /usr/lib/systemd/system 里面的 httpd.service 文件。
这是因为开机时, Systemd 只执行 /etc/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
实例
当自己写了一个脚本后,期望每次开机后,该服务能自动运行,此时就必须考虑一个开机自启的方法了,经过多方咨询后,最终决定采用systemd服务来完成,具体内容如下。
创建自己的服务
进入对应目录
cd /etc/systemd/system
创建服务文件
sudo touch apptest.service # 假如我起了一个叫apptest的服务
编辑服务内容
[Unit]
Description=apptest
After=network.target # 因我的服务需要在网络连接成功后才能正常运行,故需要等网络服务启动后才运行
[Service]
ExecStart=/home/babyfengfjx/Desktop/apptest.py # 此处就是需要启动的命令了,这个地方需要填写绝对路径,如果是后台运行的服务,不需要加nohup 这种了。
Type=simple
User=babyfengfjx # 指定用我的普通用户运行,而不是用root
[Install]
WantedBy=multi-user.target
启动服务
systemctl start apptest.service
查看服务状态
systemctl status apptest.service
通过上述命令即可查看到该服务当前运行的状态,如果是running那就OK了,如果失败了则需要具体查看一下你的这个命令部分,一般都是这里出了问题。
个人出现的问题有:
- 命令中加了nohup,之前是为了能方便在后台运行就加了这个,实际上systemd管理的服务是不需要这个部分的;
- 命令中日志输出的部分,没有使用绝对路径,导致执行的是否没有写入权限报错了;
- 我使用的是python,在开始执行的时候,我写的是
python3 /home/babyfengfjx/Desktop/apptest.py
这个时候执行出现了报错,提示有一个python库没有安装,但我明明手动执行的时候是可以的呀,最后发现该服务是以root的名义去运行的,而我这个库只在当前普通用户中有,所以才会报错,最后直接将python执行部分写入到脚本开头中就OK了; - 因为我的脚本是需要普通用户执行的,所以加了一个User字段。
设置开机自启动
systemctl enable apptest.service
就这么easy,上述操作后就完事了,后面系统无论如何重启,我的服务都能自己跑起来咯~
标签:systemd,服务,启动,开机,当前,自启动,Type,Unit From: https://www.cnblogs.com/babyfengfjx/p/18156031