在Linux中创建systemd服务

简介:systemd服务是什么?简单点来说,它就是一个‘后台’进程管理的一个服务软件。我们可以通过systemd服务管理其他不同的进程。比如我们所熟悉的nginx、mysql及php-fpm等

systemd服务是什么?简单点来说,它就是一个‘后台’进程管理的一个服务软件。我们可以通过systemd服务管理其他不同的进程。比如我们所熟悉的nginx、mysql及php-fpm等。

systemd服务是以某种格式编写的文件,其被systemd进程解析和理解文件中的内容,然后按照要求执行,而这种文件就叫systemd服务文件。这个服务文件一般都在【/usr/lib/systemd/system】和【/etc/systemd/system/】目录下,以【.service】结尾

systemd 服务文件的基本结构

systemd 服务文件由三个部分组成,分别是【Unit】、【Service】及【install】,文件扩展名为【.service】。文件格式如下所示(这是一个管理nginx服务文件):

[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network.target

[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPost=/bin/sleep 0.1
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=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
TimeoutStartSec=120
LimitNOFILE=1000000
LimitNPROC=1000000
LimitCORE=1000000

[Install]
WantedBy=multi-user.target

下面我们针对这三个组成分别来说说其作用吧

【Unit】部分

Unit部分包括服务的描述和详情。例如:描述他的作用及依赖关系等:

  • Description:systemd 服务的描述标题。主要说明当前服务是干什么的。
  • Documentation(可选):当前服务的文档。例如:nginx的官方文档
  • After(可选):说明本unit是在哪个服务启动。仅是说明服务启动的顺序而已,并没有强制要求。例如,nginx服务在network后启动【After=network.target
  • Before(可选):说明本unit是在哪个服务启动。仅是说明服务启动的顺序而已,并没有强制要求哦。
  • Requires(可选):设置服务的依赖性,本unit启动之前必须启动的服务。如果在此项设置的服务没有启动成功,那么本 unit 就不会被启动!
  • Wants(可选):与Requires 刚好相反,规范的是这个unit之后还会启动什么服务,如果这Wants 后面接的服务如果没有启动成功,不会影响到这个unit本身!
  • Conflicts(可选):配置与当前服务互斥的服务。如果本unit启动了,则指定的服务就不能启动,相反亦是如此。

【Service】部分

主要有关systemd服务执行和终止的相关命令的配置

  • user:设置当前unit启动的用户名
  • PIDFile:当前unit的主进程的pid保存的文件的绝对路径,形成$MAINPID。用于重启和关闭unit
  • ExecStart:【systemctl start】时需要执行的命令,用于启动某个服务。
  • ExecReload:【systemctl reload】时需要执行的命令。一般都是重新加载服务的配置信息。对于执行磁盘I/O(例如数据库)的服务,最好平滑的终止它们并重新启动。
  • Restart:【systemctl restart】时执行的命令,用于重启某个服务时需要执行的命令。

no(默认值):退出后不会重启

on-success:只有正常退出时(退出状态码为0),才会重启

on-failure:非正常退出时(退出状态码非0),包括被信号终止和超时,才会重启

on-abnormal:只有被信号终止和超时,才会重启

on-abort:只有在收到没有捕捉到的信号终止时,才会重启

on-watchdog:超时退出,才会重启

always:不管是什么退出原因,总是重启

  • ExecStop:systemctl stop】时执行的命令,用于关闭某个服务
  • KillMode:服务停止类型。

control-group:默认值。停止时杀死所有子进程

process:只杀主进程

none:只停止服务,不杀进程

mixed:主进程将收到 SIGTERM 信号,子进程收到 SIGKILL 信号

  • Type:服务进程启动类型。其值如下几个:simple、exec、forking、oneshot、dbus、notify以及idle等

simple:默认值,这个服务主要由ExecStart设置的程序来启动,启动后常驻于内存中

forking:由ExecStart指定的启动的程序通过spawns产生子进程提供服务,然后父进程退出

oneshot:与simple类似,不过这个程序在工作完毕后就结束了,不会常驻在内存中

dbus:与simple类似,但这个服务必须要在取得一个D-Bus的名称后,才会继续运行!因此设置这个项目时,通常也要设置 BusName= 才行

idle:与simple类似,要执行这个服务必须要所有的工作都顺利执行完毕后才会执行。这类的服务通常是开机到最后才执行服务

notify:与simple类似,但这个服务必须要收到一个sd_notify() 函数发送的消息后,才会继续运行

【install】部分

主要说明如何安装这个配置文件,把该 unit 安装在哪个 target上,做到开机自启。其实就是在使用【systemctl enable】时,进行创建符号连接会识别到[Install]字段的内容进行安装,主要是创建软链到【/etc/systemd/system/】目录下

Target的含义是服务组,表示一组服务。例如:

multi-user.target:Systemd 默认的启动 Target,在这个组里的所有服务,都将开机自动启动

这个部分主要三个字段:

  • WantedBy:这个设置后面接的大部分是 *.target 。意思是,这个unit本身该附挂在哪个 target 下面
  • Also(可选):当目前这个unit被设置开机自启时,Also 后面接的unit也要开机自启的意思
  • Alias(可选):当systemctl enable相关的服务时,则此服务会进行链接文件的创建!默认开启!

了解了sytemd服务文件结构后,我们就可以自己去创建服务了,比如:创建一个php-fpm的sytemd服务文件。进入【/usr/lib/systemd/system】目录下,创建一个php-fpm.service的服务文件在文件中添加如下信息:

[Unit]
Description=The PHP FastCGI Process Manager
Documentation=http://php.net/docs.php
After=network.target

[Service]
Type=simple
PIDFile=/usr/local/php/var/run/php-fpm.pid
ExecStart=/usr/local/php/sbin/php-fpm --nodaemonize --fpm-config /usr/local/php/etc/php-fpm.conf
ExecReload=/bin/kill -USR2 $MAINPID
LimitNOFILE=1000000
LimitNPROC=1000000
LimitCORE=1000000

[Install]
WantedBy=multi-user.target

到此sytemd服务编写就已经完成了,最后的最后,我们需要让systemd重新加载服务文件,使其生效,执行如下命令:

systemctl daemon-reload

现实工作中我们可能需要普通用户去创建系统服务文件,甚至以某个普通用户去执行服务。因此我们可以在用户根目录下的【/home/userName/.config/systemd/user】目录下创建服务文件。

userName:是用户名

.config:这个目录可能不存在,可以自己创建,其他亦是如此。

如果创建了用户服务,可以使用一下命令重新加载用户服务:

systemctl --user daemon-reload

完成上述的配置后我们就可以使用 systemctl 或者 service命令启动,关闭等操作了。

查看某个服务【systemctl status nginx】

第一行是服务的描述标题。

第二行Loaded是服务文件的位置,是否开机自启动。enabled代表开机自启动

第三行Active:是否启动。active(running)表示已启动正在运行

第四行Docs:服务文档链接

第五行Process:启动的命令 

第六行Main PID:当前服务的主进程的PID

第七行CGroup:当前服务的所有子进程。上图中nginx中有一个master管理进程以及一个nginx工作进程

我们也可以使用service命令进行查看,需要注意的是service格式与systemctl不同,service第二个参数是服务的名称 第三个才是需要执行的命令。例如:

service nginx status

有遗漏或者不对的可以在我的公众号留言哦

编程经验共享公众号二维码

编程经验共享公众号二维码
更多内容关注公众号
Copyright © 2021 编程经验共享 赣ICP备2021010401号-1