Linux 服务创建 (Systemd Service)
什么是服务?有什么用?
Linux下面的服务可以理解为和Windows上的,也可以理解为一种守护(Daemon)进程,通常是在后台默默运行的基础设施应用,如数据库、驱动等。
通过创建服务,我们可以将自己的应用设为开机启动,并可以自动重启。
本文参考了How to create a systemd service in Linux,基本上就是翻译了他。
服务配置文件 (Systemd Service File)
Debian中以.service文件形式储存在/etc/systemd/system中
一个常见的服务配置文件如下,可见其由”Unit”、”Service”、”Install”三部分组成,
1 |
|
Unit 部分
这部分记录了服务的基本信息,有以下常用部分:
- 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
1 |
|
开机时运行一个脚本
1 |
|