Systemd的Unit文件; systemctl自定义服务启动

CentOS7的服务systemctl脚本存放在:/usr/lib/systemd/,有系统(system)和用户(user)之分,需要开机不登陆就能运行的程序,存在系统服务里,即:/usr/lib/systemd/system目录下.

ubuntu的在/etc//systemd/system目录下.
CentOS7的每一个服务以.service结尾,一般会分为3部分:[Unit]、[Service]和[Install] 

[Unit]部分主要是对这个服务的说明,内容包括Description和After,Description 用于描述服务,After用于描述服务类别
 

[Service]部分是服务的关键,是服务的一些具体运行参数的设置.

Type=forking是后台运行的形式,

User=users是设置服务运行的用户,

Group=users是设置服务运行的用户组,

PIDFile为存放PID的文件路径,

ExecStart为服务的具体运行命令,

ExecReload为重启命令,

ExecStop为停止命令,

PrivateTmp=True表示给服务分配独立的临时空间

注意:[Service]部分的启动、重启、停止命令全部要求使用绝对路径,使用相对路径则会报错!

路径

说明

/etc/systemd/system

系统或用户提供的配置文件

/run/systemd/system

软件运行时生成的配置文件

/usr/lib/systemd/system

系统或第三方软件安装时添加的配置文件

一、Unit 段

Description 一段描述这个 Unit 文件的文字,通常只是简短的一句话。

Documentation 指定服务的文档,可以是一个或多个文档的URL路径。

Requires  依赖的其他 Unit 列表,列在其中的 Unit 模块会在这个服务启动的同时被启动,并且如果其中有任意一个服务启动失败,这个服务也会被终止。

Wants   与 Requires 相似,但只是在被配置的这个 Unit 启动时,触发启动列出的每个 Unit 模块,而不去考虑这些模块启动是否成功。

After  与 Requires 相似,但会在后面列出的所有模块全部启动完成以后,才会启动当前的服务。

Before   与 After 相反,在启动指定的任一个模块之前,都会首先确保当前服务已经运行。

BindsTo  与 Requires 相似,但是一种更强的关联。启动这个服务时会同时启动列出的所有模块,当有模块启动失败时终止当前服务。反之,只要列出的模块全部启动以后,也会自动启动当前服务。并且这些模块中有任意一个出现意外结束或重启,这个服务会跟着终止或重启。

PartOf  这是一个 BindTo 作用的子集,仅在列出的任何模块失败或重启时,终止或重启当前服务,而不会随列出模块的启动而启动。

OnFailure  当这个模块启动失败时,就自动启动列出的每个模块。

Conflicts  与这个模块有冲突的模块,如果列出模块中有已经在运行的,这个服务就不能启动,反之亦然。

上面这些配置中,除了 Description 外,都能够被添加多次。比如前面第一个例子中的After参数在一行中使用空格分隔指定所有值,也可以像第二个例子中那样使用多个After参数,在每行参数中指定一个值。

二、Install 段

这个段中的配置与 Unit 有几分相似,但是这部分配置需要通过 systemctl enable 命令来激活,并且可以通过 systemctl disable 命令禁用。另外这部分配置的目标模块通常是特定启动级别的 .target 文件,用来使得服务在系统启动时自动运行。

WantedBy   和前面的 Wants 作用相似,只是后面列出的不是服务所依赖的模块,而是依赖当前服务的模块。

RequiredBy  和前面的 Requires 作用相似,同样后面列出的不是服务所依赖的模块,而是依赖当前服务的模块。

Also  当这个服务被 enable/disable 时,将自动 enable/disable 后面列出的每个模块。

上面的两个例子中使用的都是 “WantedBy=multi-user.target” 表明当系统以多用户方式(默认的运行级别)启动时,这个服务需要被自动运行。当然还需要 systemctl enable 激活这个服务以后自动运行才会生效。关于 Linux 系统启动时的运行级别,可以参看这篇文章。

三、Service 段

这个段是 .service 文件独有的,也是对于服务配置最重要的部分。这部分的配置选项非常多,主要分为服务生命周期控制和服务上下文配置两个方面,下面是比较常用到的一些参数。

服务生命周期控制相关的参数:

Type  服务的类型,常用的有 simple(默认类型) 和 forking。默认的 simple 类型可以适应于绝大多数的场景,因此一般可以忽略这个参数的配置。而如果服务程序启动后会通过 fork 系统调用创建子进程,然后关闭应用程序本身进程的情况,则应该将 Type 的值设置为 forking,否则 systemd 将不会跟踪子进程的行为,而认为服务已经退出。

RemainAfterExit  值为 true 或 false(也可以写 yes 或 no),默认为 false。当配置值为 true 时,systemd 只会负责启动服务进程,之后即便服务进程退出了,systemd 仍然会认为这个服务是在运行中的。这个配置主要是提供给一些并非常驻内存,而是启动注册后立即退出然后等待消息按需启动的特殊类型服务使用

ExecStart  这个参数是几乎每个 .service 文件都会有的,指定服务启动的主要命令,在每个配置文件中只能使用一次。

ExecStartPre  指定在启动执行 ExecStart 的命令前的准备工作,可以有多个,如前面第二个例子中所示,所有命令会按照文件中书写的顺序依次被执行。

ExecStartPost  指定在启动执行 ExecStart 的命令后的收尾工作,也可以有多个。

TimeoutStartSec  启动服务时的等待的秒数,如果超过这个时间服务任然没有执行完所有的启动命令,则 systemd 会认为服务自动失败。这一配置对于使用 Docker 容器托管的应用十分重要,由于 Docker 第一次运行时可以能会需要从网络下载服务的镜像文件,因此造成比较严重的延时,容易被 systemd 误判为启动失败而杀死。通常对于这种服务,需要将 TimeoutStartSec 的值指定为 0,从而关闭超时检测,如前面的第二个例子。

ExecStop  停止服务所需要执行的主要命令。

ExecStopPost  指定在 ExecStop 命令执行后的收尾工作,也可以有多个。

TimeoutStopSec  停止服务时的等待的秒数,如果超过这个时间服务仍然没有停止,systemd 会使用 SIGKILL 信号强行杀死服务的进程。

Restart 这个值用于指定在什么情况下需要重启服务进程。常用的值有 no,on-success,on-failure,on-abnormal,on-abort 和 always。默认值为 no,即不会自动重启服务。这些不同的值分别表示了在哪些情况下,服务会被重新启动,参见下表。

服务退出原因

no

always

on-failure

on-abnormal

on-abort

no-success

正常退出

异常退出

启动/停止超时

被异常KILL

RestartSec 如果服务需要被重启,这个参数的值为服务被重启前的等待秒数。

ExecReload重新加载服务所需执行的主要命令。

服务上下文配置相关的参数:

Environment  为服务添加环境变量,如前面的第一个例子中所示。

EnvironmentFile指定加载一个包含服务所需的环境变量列表的文件,文件中的每一行都是一个环境变量的定义。

Nice服务的进程优先级,值越小优先级越高,默认为0。-20为最高优先级,19为最低优先级。

WorkingDirectory  指定服务的工作目录。

RootDirectory  指定服务进程的根目录( / 目录),如果配置了这个参数后,服务将无法访问指定目录以外的任何文件。

User  指定运行服务的用户,会影响服务对本地文件系统的访问权限。

Group  指定运行服务的用户组,会影响服务对本地文件系统的访问权限。

  • LimitCPU / LimitSTACK / LimitNOFILE / LimitNPROC 等

限制特定服务可用的系统资源量,例如 CPU,程序堆栈,文件句柄数量,子进程数量… 不再展开说明了,值的含义可参考 Linux 文档资源配额部分中 RLIMIT_ 开头的那些参数们。

列完这么一大推参数的我也是醉了(这些都是常用的参数,不常用的还没写咧),但其实嘛,Systemd 的精华也就在此了。再仔细一推敲,这么些冗长的参数之间还是有些规律的,并且大多可以望文生义,因此写 Unit 文件的差事本身倒并不让人觉得枯燥。反观过去需要学习N种不同配置格式来管理N种不同的系统资源的方法,Systemd的理念实在是先进了太多了。而这些参数云云,大概只有用得多了,才会觉得它们看起来不那么讨厌了吧o(//_//)o

示例

frp 示例

[Unit]
Description=frpc daemon
After=syslog.target  network.target
Wants=network.target[Service]
Type=simple
ExecStart=/frp_0.17.0_linux_arm/frpc -c /frp_0.17.0_linux_arm/frpc.ini
Restart= always
RestartSec=1min[Install]
WantedBy=multi-user.target

python 示例

[Unit]
Description=led daemon
After=syslog.target  network.target
Wants=network.target[Service]
# 指定目录
WorkingDirectory=/home/witcomm/witposeidon-single-backend/
Type=simple
ExecStart=/home/witcomm/.virtualenvs/witposeidon-single-backend-YxtQLtDF/bin/python /home/witcomm/witposeidon-single-backend/LED_tcp_new.py
# 指定用户
User=witcomm
Restart= always
RestartSec=2[Install]
WantedBy=multi-user.target

reids 示例

[Unit]
Description=Advanced key-value store
After=network.target
Documentation=http://redis.io/documentation, man:redis-server(1)[Service]
Type=forking
ExecStart=/usr/bin/redis-server /etc/redis/redis.conf
PIDFile=/var/run/redis/redis-server.pid
TimeoutStopSec=0
Restart=always
User=redis
Group=redisExecStartPre=-/bin/run-parts --verbose /etc/redis/redis-server.pre-up.d
ExecStartPost=-/bin/run-parts --verbose /etc/redis/redis-server.post-up.d
ExecStop=-/bin/run-parts --verbose /etc/redis/redis-server.pre-down.d
ExecStop=/bin/kill -s TERM $MAINPID
ExecStopPost=-/bin/run-parts --verbose /etc/redis/redis-server.post-down.dUMask=007
PrivateTmp=yes
PrivateDevices=yes
ProtectHome=yes
ReadOnlyDirectories=/
ReadWriteDirectories=-/var/lib/redis
ReadWriteDirectories=-/var/log/redis
ReadWriteDirectories=-/var/run/redis
CapabilityBoundingSet=~CAP_SYS_PTRACE# redis-server writes its own config file when in cluster mode so we allow
# writing there (NB. ProtectSystem=true over ProtectSystem=full)
ProtectSystem=true
ReadWriteDirectories=-/etc/redis[Install]
WantedBy=multi-user.target
Alias=redis.service

sshd 示例

[Unit]
Description=OpenBSD Secure Shell server
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run[Service]
EnvironmentFile=-/etc/default/ssh
ExecStartPre=/usr/sbin/sshd -t
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/usr/sbin/sshd -t
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify[Install]
WantedBy=multi-user.target
Alias=sshd.service

logstash示例

[Unit]
Description=logstash daemon
After=syslog.target  network.target
Wants=network.target[Service]
Type=simple
WorkingDirectory=/root/
ExecStart=/root/logstash-7.2.0/bin/logstash -f /root/logstash-7.2.0/logyml/test_json.yml
Restart= always
RestartSec=1min
User=root[Install]
WantedBy=multi-user.target


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部