【systemd】systemd.service

systemd即为system daemon,是linux下的一种init软件,由Lennart Poettering带头开发,并在LGPL 2.1及其后续版本许可证下开源发布,开发目标是提供更优秀的框架以表示系统服务间的依赖关系,并依此实现系统初始化时服务的并行启动,同时达到降低Shell的系统开销的效果,最终代替现在常用的System V与BSD风格init程序。

 与多数发行版使用的System V风格init相比,systemd采用了以下新技术:

 (1) 采用Socket激活式与总线激活式服务,以提高相互依赖的各服务的并行运行性能;

 (2) 用Cgroups代替PID来追踪进程,以此即使是两次fork之后生成的守护进程也不会脱离systemd的控制



例 1. 简单服务

下面的单元文件创建了一个运行 /usr/sbin/foo-daemon 守护进程的服务。 未设置 Type= 等价于 Type=simple 默认设置。 systemd 执行守护进程之后, 即认为该单元已经启动成功。

#################################

[Unit]

Description=简单的Foo服务

[Service]

ExecStart=/usr/sbin/foo-daemon

[Install]

WantedBy=multi-user.target

##################################

注意,本例中的 /usr/sbin/foo-daemon 必须在启动后持续运行到服务被停止。 如果该进程只是为了派生守护进程,那么应该使用 Type=forking

因为没有设置 ExecStop= 选项, 所以在停止服务时,systemd 将会直接向该服务启动的所有进程发送 SIGTERM 信号。 若超过指定时间依然存在未被杀死的进程,那么将会继续发送 SIGKILL 信号。 详见 systemd.kill(5) 手册。

默认的 Type=simple 并不包含任何通知机制(例如通知"服务启动成功")。 要想使用通知机制,应该将 Type= 设为其他非默认值: Type=notify 可用于能够理解 systemd 通知协议的服务; Type=forking 可用于能将自身切换到后台的服务; Type=dbus 可用于能够在完成初始化之后获得一个 D-Bus 名称的单元。

例 2. 一次性服务

Type=oneshot 用于那些只需要执行一次性动作而不需要持久运行的单元, 例如文件系统检查或者清理临时文件。 此类单元, 将会在启动后一直等待指定的动作完成, 然后再回到停止状态。 下面是一个执行清理动作的单元:

#################################

[Unit]

Description=清理老旧的 Foo 数据

[Service]

Type=oneshot

ExecStart=/usr/sbin/foo-cleanup

[Install]

WantedBy=multi-user.target

##################################

注意,在 /usr/sbin/foo-cleanup 执行结束前, 该服务一直处于"启动中"(activating)状态,而一旦执行结束,该服务又立即变为"停止"(inactive)状态。 也就是说,对于 Type=oneshot 类型的服务,不存在"活动"(active)状态。 这意味着,如果再一次启动该服务,将会再一次执行该服务定义的动作。 注意,在先后顺序上晚于该服务的单元, 将会一直等到该服务变成"停止"(inactive)状态后, 才会开始启动。

Type=oneshot 是唯一可以设置多个 ExecStart= 指令的服务类型。 多个 ExecStart= 指令将按照它们出现的顺序依次执行, 一旦遇到错误,就会立即停止,不再继续执行, 同时该服务也将进入"失败"(failed)状态。

例 3. 可停止的一次性服务

有时候,单元需要执行一个程序以完成某个设置(启动), 然后又需要再执行另一个程序以撤消先前的设置(停止), 而在设置持续有效的时段中,该单元应该视为处于"活动"(active)状态, 但实际上并无任何程序在持续运行。 网络配置服务就是一个典型的例子。 此外,只能启动一次(不可多次启动)的一次性服务,也是一个例子。

可以通过设置 RemainAfterExit=yes 来满足这种需求。 在这种情况下,systemd 将会在启动成功后将该单元视为处于"活动"(active)状态(而不是"停止"(inactive)状态)。 RemainAfterExit=yes 虽然可以用于所有 Type= 类型, 但是在实践中主要用于 Type=oneshot 和 Type=simple 类型。 对于 Type=oneshot 类型, systemd 一直等到服务启动成功之后,才会将该服务置于"活动"(active)状态。 所以,依赖于该服务的其他单元必须等待该服务启动成功之后,才能启动。 但是对于 Type=simple 类型, 依赖于该服务的其他单元无需等待,将会和该服务同时并行启动。 下面的类似展示了一个简单的静态防火墙服务:

####################################

[Unit]

Description=简单的静态防火墙

[Service]

Type=oneshot

RemainAfterExit=yes

ExecStart=/usr/local/sbin/simple-firewall-start

ExecStop=/usr/local/sbin/simple-firewall-stop

[Install]

WantedBy=multi-user.target

####################################

因为服务启动成功后一直处于"活动"(active)状态, 所以再次执行 systemctl start 命令不会有任何效果。

例 4. 传统的服务

多数传统的守护进程(服务)在启动时会转入后台运行。 systemd 通过 Type=forking 来支持这种工作方式。 对于这种类型的服务,如果最初启动的进程尚未退出, 那么该单元将依然处于"启动中"(activating)状态。 当最初的进程成功退出, 并且至少有一个进程仍然在运行(并且 RemainAfterExit=no), 该服务才会被视为处于"活动"(active)状态。

对于单进程的传统服务,当最初的进程成功退出后, 将会只剩单独一个进程仍然在持续运行, systemd 将会把这个唯一剩余的进程视为该服务的主进程。 仅在这种情况下,才将可以在 ExecReload=, ExecStop= … 之类的选项中使用 $MAINPID 变量。

对于多进程的传统服务,当最初的进程成功退出后,将会剩余多个进程在持续运行, 因此,systemd 无法确定哪一个进程才是该服务的主进程。 在这种情况下,不可以使用 $MAINPID 变量。 然而,如果主进程会创建传统的PID文件, 那么应该将 PIDFile= 设为此PID文件的绝对路径, 以帮助 systemd 从该PID文件中读取主进程的PID,从而帮助确定该服务的主进程。 注意,守护进程必须在完成初始化之前写入PID文件, 否则可能会导致 systemd 读取失败(读取时文件不存在)。

下面是一个单进程传统服务的示例:

#################################

[Unit]

Description=一个单进程传统服务

[Service]

Type=forking

ExecStart=/usr/sbin/my-simple-daemon -d

[Install]

WantedBy=multi-user.target

################################## 

参见 systemd.kill(5) 以了解如何结束服务进程。

下面是一个多进程传统服务的示例:


##########################################################

[Unit]

Description=The NGINX HTTP and reverse proxy server

After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]

Type=forking

PIDFile=/run/nginx.pid

ExecStartPre=/usr/sbin/nginx -t

ExecStart=/usr/sbin/nginx

ExecReload=/usr/sbin/nginx -s reload

ExecStop=/bin/kill -s QUIT $MAINPID

PrivateTmp=true

[Install]

WantedBy=multi-user.target

########################################################### 

例 5. DBus 服务

对于需要在 D-Bus 系统总线上注册一个名字的服务, 应该使用 Type=dbus 并且设置相应的 BusName= 值。 

该服务不可以派生任何子进程。 一旦从 D-Bus 系统总线成功获取所需的名字,该服务即被视为初始化成功。 

下面是一个典型的 D-Bus 服务:

#################################

[Unit]

Description=一个简单的 DBus 服务

[Service]

Type=dbus

BusName=org.example.simple-dbus-service

ExecStart=/usr/sbin/simple-dbus-service

[Install]

WantedBy=multi-user.target

###################################

对于基于 D-Bus 启动的服务来说, 不可以包含 "[Install]" 小节, 而是应该在对应的 D-Bus service 文件中设置 SystemdService= 选项, 例如(/usr/share/dbus-1/system-services/org.example.simple-dbus-service.service):

##################################

[D-BUS Service]

Name=org.example.simple-dbus-service

Exec=/usr/sbin/simple-dbus-service

User=root

SystemdService=simple-dbus-service.service

###################################


参见 systemd.kill(5) 手册以了解如何结束服务进程。

例 6. 能够通知初始化已完成的服务

Type=simple 类型的服务非常容易编写, 但是无法将"启动成功"的消息及时通知给 systemd 是一个重大缺陷。 Type=notify 可以弥补该缺陷, 它支持将"启动成功"的消息及时通知给 systemd 。 下面是一个典型的例子:

####################################

[Unit]

Description=Simple notifying service

[Service]

Type=notify

ExecStart=/usr/sbin/simple-notifying-service

[Install]

WantedBy=multi-user.target

####################################

注意,该守护进程必须支持 systemd 通知协议, 否则 systemd 将会认为该服务一直处于"启动中"(activating)状态,并在超时后将其杀死。 关于如何支持该通知协议,参见 sd_notify(3) 手册。

参见 systemd.kill(5) 手册以了解如何结束服务进程。


参考

systemd详解

https://blog.linuxeye.cn/400.html

Systemd 入门教程:命令篇

http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html

Systemd 入门教程:实战篇

http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-part-two.html

CentOS 7之Systemd详解之服务单元设置system.service

http://blog.csdn.net/yuesichiu/article/details/51485147

https://www.freedesktop.org/software/systemd/man/systemd.service.html

CentOS 7之Systemd详解之单元配置systemd.unit

http://blog.csdn.net/yuesichiu/article/details/51331136

CentOS 7系统详细开机启动流程和关机流程

http://blog.csdn.net/yuesichiu/article/details/51350654

NGINX systemd service file

https://www.nginx.com/resources/wiki/start/topics/examples/systemd

http://images.linoxide.com/systemd-vs-sysVinit-cheatsheet.pdf

Centos7 创建服务

http://blog.csdn.net/zhangxtn/article/details/50462008

编写systemd service文件

https://zh.opensuse.org/openSUSE:How_to_write_a_systemd_service

認識系統服務

http://linux.vbird.org/linux_basic/0560daemons.php

systemd System and Service Manager

https://www.freedesktop.org/wiki/Software/systemd/

https://wiki.archlinux.org/index.php/systemd_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)

https://www.freedesktop.org/software/systemd/man/systemd.service.html#Type= 

systemd.service 中文手册

http://www.jinbuguo.com/systemd/systemd.service.html

systemd 使用简介

https://jin-yang.github.io/post/linux-systemd.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,335评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,895评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,766评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,918评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,042评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,169评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,219评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,976评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,393评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,711评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,876评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,562评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,193评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,903评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,699评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,764评论 2 351

推荐阅读更多精彩内容