什么是服务?有什么用?#
Linux下面的服务可以理解为和Windows上的,也可以理解为一种守护(Daemon)进程,通常是在后台默默运行的基础设施应用,如数据库、驱动等。
通过创建服务,我们可以将自己的应用设为开机启动,并可以自动重启。
本文参考了How to create a systemd service in Linux,基本上就是翻译了他。
服务配置文件 (Systemd Service File)#
Debian中以.service文件形式储存在/etc/systemd/system中
一个常见的服务配置文件如下,可见其由"Unit"、“Service”、“Install"三部分组成,
[Unit]
Description=Apache web server
After=network.target
Before=nextcloud-web.service
[Service]
ExecStart=/usr/local/apache2/bin/httpd -D FOREGROUND -k start
ExecReload=/usr/local/apache2/bin/httpd -k graceful
Type=notify
Restart=always
[Install]
WantedBy=default.target
RequiredBy=network.targetUnit 部分#
这部分记录了服务的基本信息,有以下常用部分:
- Description 给人看的描述
- Wants 这个服务需要依赖与某个服务,如xxx.service。
- Requires 同上,但本项的服务如果依赖不存在或者失败则会不运行(也就是上面的Wants就是嘴上说说)。
- After
在什么阶段之后运行,通常是xxx.target,比如开启后运行就是
multi-user.target,关机就是poweroff.target,要求有网络就是network.target等。 - Before 在什么服务之前运行,基本同上。
Service 部分#
这部分记录了本服务应该如何运行,有以下常用部分:
- ExecStart
这个服务运行程序的命令,比如执行一下apt更新就写
apt update - ExecReload
少见。使用
systemctl restart等命令时执行的重启命令,如果你的服务重启需要特定的命令,或者是一些操作储存数据的服务,你需要使用该项优雅地重启。 - Type 服务进程的类型,通常使用simple,当然还有exec、forking之类的。像nginx这种有一个短暂的中间父进程运营应用的,必须设置为forking否则systemd会认为运行失败。详见最后面的Type介绍节。
- Restart
少见。服务重启的时机,可以是关闭
no或者几种异常情况on-failure、on-abnormal等。
Install 部分#
这部分决定了使用systemctl enable和systemctl disable启动和关闭服务的处理,有以下常用部分:
- WantedBy 和 Unit 段的 Wants 作用相似,填写的内容类似于Unit部分After和Before中的各种target,只有后面列出的不是服务所依赖的模块,而是依赖当前服务的模块,当前 Unit 激活时(enable)符号链接会放入 /etc/systemd/system目录下面以<Target名>+.wants后缀构成的子目录中。
- RequiredBy 和 Unit 段的 Requires作用相似,同上,当前 Unit 激活时,符号链接会放入 /etc/systemd/system目录下面以<Target 名>+.required后缀构成的子目录中。
- Also 当前 Unit enable/disable 时,同时 enable/disable 的其他 Unit。
- Alias 当前 Unit 可用于启动的别名。
WantedBy、RequiredBy:在 .wants/ 或 .requires/ 子目录中为服务建立相应的链接。这样做的效果是当列表中的服务启动,本服务也会启动。
要实现开机启动,在Unit中写After或者在Install中写WantedBy都是可以的。
服务安装、运行#
和Windows一样,服务的运行也是分用户的,Linux里的服务也分为Root用户运行和其他用户运行,区别只是服务配置文件的“存放”的位置。
Root用户运行的服务,配置讲上一章节写的xxx.service文件存放到/etc/systemd/system/,使用其他用户运行的服务,文件存放到~/.config/systemd/user/,你可能需要手动创建这个目录。
文件存放到位后,不重启系统则需要使用systemctl daemon-reload或systemctl --user daemon-reload刷新配置文件,后者是其他用户运行服务时使用的。
后面安装、运行等非Root用户服务操作都添加
--user参数
直接systemctl enable xxx.service即可安装、启动,通过is-enabled可以查看是否被安装,然后就是常规的start、stop、restart命令,这里略过。
服务运行类型 Service Type#
在配置文件的[Service]部分中的Type,常用的几个简单介绍如下:
| Type | 介绍 |
|---|---|
| oneshot | 适合运行一次、短暂立刻退出的服务,可能需要同时设置 RemainAfterExit=yes 使得 systemd 在服务进程退出之后仍然认为服务处于激活状态。 |
| simple | 立刻普通地启动程序。 |
| idle | 基本等于simple,但是等待其他服务启动、处理都完成了,相当于让位,也避免启动日志混在一起。 |
| notify | 基本等于simple,但在就绪后向systemd发送一个信号 |
| forking | 如果运行的程序有个短暂的中间父进程,或者说调用了fork(),父进程退出后应该视为正常,则使用此类型,应同时指定 PIDFile=,以便 systemd 能够跟踪服务的主进程。 |
详细文档请看该链接
简单例子#
nginx#
[Unit]
Description=nginx - high performance web server
#描述服务
After=network.target remote-fs.target nss-lookup.target
#描述服务类别
[Service]
Type=forking
#后台运行的形式
PIDFile=/usr/local/nginx/logs/nginx.pid
#PID文件的路径
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
#启动前准备 校验配置文件是否错误
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
#启动命令 指定配置文件
ExecReload=/usr/local/nginx/sbin/nginx -s reload
#重启命令
ExecStop=/usr/local/nginx/sbin/nginx -s stop
#停止命令
ExecQuit=/usr/local/nginx/sbin/nginx -s quit
#强制停止
PrivateTmp=true
#给服务分配临时空间
[Install]
WantedBy=multi-user.target开机时运行一个脚本#
[Unit]
Description = Run script after system booted.
# 要求脚本具有可执行权限
ConditionFileIsExecutable=/usr/bin/script.sh
[Service]
ExecStart = /usr/bin/script.sh
[Install]
WantedBy = multi-user.target