如何编写systemd

本文详细介绍了在CentOS系统中如何编写systemd服务,包括各种配置参数的含义和使用场景,如Type、ExitType、RemainAfterExit等。通过具体的例子解释了如何配置启动、重启和停止服务的相关指令,帮助读者理解systemd服务的管理和控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

仅以linux —— Centos为例,若其他系统,例如suse等参见官方文档

例:

[Unit]     

Description=test deamon   ##描述

After=rc-local.service     ##在after=的程序启动之后程序才会启动

[Service]

Type=simple

User=root

Group=root

WorkingDirectory=/home

ExecStart=/usr/bin/python test.py

Restart=always

[Install]

WantedBy=multi-user.target

Type= 参数说明

官方提供一下参数:

 simpleexecforkingoneshotdbusnotify or idle

Type=simple  说明:

  在有些情况下 systemctl start *** 这条命令即使执行成功,服务也没有运行,原因在于此条配置,simple为默认值(必须写,不写默认值为oneshot),在你指定ExecStart=所配置的进程视为主进程,因为服务管理器将在创建主服务进程之后和执行服务的二进制文件之前立即启动后续单元。请注意,这意味着即使无法成功调用服务的二进制文件(例如,因为选定的User=不存在,或者服务二进制文件丢失),简单服务的systemctl start命令行也将报告成功。

Type=exec   说明:

  exec类型类似于simple,但是服务管理器会考虑在主服务二进制文件执行后立即启动该单元。这意味着如果二进制文件丢失或者选定的User=不存在,systemctl start 将报错

Type=forking  说明:

  如果设置为forking,则会将execut=所配置的进程将调用fork()作为其启动的一部分,这意味着启动完成后父进程退出,子进程作为主服务进程运行,当父进程退出时,服务管理器默认该单元已经启动,通常搭配PIDFlie=选项,以便systemd能够可靠的识别服务的主要进程

Type=oneshot  说明

  如果没有指定Type=ExecStart=的话,Type=oneshot是默认的。请注意,如果使用此选项而没有RemainAfterExit=服务将永远不会进入活动单元状态,而是直接从激活转换到停用死亡,因为没有配置应连续运行的进程。

Type=notify  说明:

  notify的行为类似于exec但是,当服务完成启动时,预计会通过sd_notify(3)或等效的调用发送通知消息。发送此通知消息后,systemd将继续启动后续装置。如果使用此选项,NotifyAccess=(见下文)应设置为打开对systemd提供的通知套接字的访问。如果NotifyAccess=缺失或设置为none,它将被强制设置为main

Type参数选择官方建议:

通常建议尽可能对长时间运行的服务使用Type=simple,因为这是最简单、最快的选项。但是,由于这种服务类型不会传播服务启动失败,并且不允许在服务初始化完成后对其他单元进行排序(例如,如果客户端需要通过某种形式的IPC连接到服务,并且IPC通道仅由服务本身建立,而不是通过套接字或总线激活或类似方式提前建立),这在许多情况下可能是不够的。如果是这样,notifydbus(后者仅在服务提供D-Bus接口的情况下)是首选选项,因为它们允许服务程序代码精确地安排何时考虑服务成功启动以及何时继续后续单元。notify服务类型需要服务代码库中的显式支持(因为sd_notify()或等效的API需要由服务在适当的时间调用)——如果不支持,那么分叉是一种替代方法:它支持传统的UNIX服务启动协议。最后,对于足以确保服务二进制文件被调用的情况,以及服务二进制文件本身不执行或很少执行初始化(并且其初始化不太可能失败)的情况,exec可能是一个选项。请注意,使用简单以外的任何类型都可能会延迟启动过程,因为服务管理器需要等待服务初始化完成。因此,建议不要不必要地使用简单类型以外的任何类型。(还要注意,对于长时间运行的服务,通常不建议使用idleoneshot)

ExitType=

  ExitType=main  说明:

         如果设置为main(默认值),服务管理器将认为该单元在主进程(根据类型=)退出时已停止。因此,它不能与Type=oneshot一起使用。

  ExitType=cgroup  说明:

      如果设置为cgroup,只要cgroup中至少有一个进程没有退出,该服务将被视为正在运行。

官方使用建议:

      当服务具有已知的分叉模型并且可以可靠地确定主进程时,通常建议使用ExitType=mainExitType= cgroup是指分叉模型事先未知且可能没有特定主进程的应用程序。它非常适合临时或自动生成的服务,例如桌面环境中的图形应用程序。

RemainAfterExit=

  RemainAfterExit=yes/no  说明:

         接受一个布尔值,该值指定服务是否应被视为活动的,即使它的所有进程都已退出。默认为no

GuessMainPID=

  接受一个布尔值,该值指定如果不能可靠地确定服务的主PIDsystemd是否应该尝试猜测它。除非设置了类型=分叉并且未设置PIDFile=否则忽略此选项,因为对于其他类型或显式配置的PIDFile,主PID file总是已知的。如果一个守护进程包含多个进程,猜测算法可能会得出不正确的结论。如果无法确定主PID,服务的故障检测和自动重启将无法可靠工作。默认为是。

PIDFile=

  后面通常跟一个文件路径,如果不指定绝对路径,则默认相对路径为/run/,通常与Type=forking一起使用;服务管理器不会写入此处配置的文件,但如果文件仍然存在,它会在服务关闭后删除该文件。

  官方建议:

     请注意,在现代项目中应该避免PID文件。在可能的情况下,使用Type=notifyType=simple,这不需要使用PID文件来确定服务的主要进程,并避免不必要的分叉。

ExecStart=

启动此服务时执行的带有参数的命令。根据下面描述的规则,该值被分成零个或多个命令行(参见下面的命令行部分) 除非Type=oneshot,否则只能给出一个命令。当使用Type=oneshot时,可以指定零个或多个命令。可以通过在同一个指令中提供多个命令行来指定命令,或者,可以多次指定该指令以获得相同的效果。如果将空字符串分配给此选项,将重置要启动的命令列表,以前分配的此选项将无效。如果没有指定ExecStart=则服务必须有RemainAfterExit = yes和至少一个ExecStop= line集。(同时缺少ExecStart=ExecStop=的服务无效。) 对于每个指定的命令,第一个参数必须是可执行文件的绝对路径或不带任何斜杠的简单文件名。可选地,该文件名可以以许多特殊字符作为前缀:

ExecStartPre=ExecStartPost=

  分别在ExecStart=中的命令之前或之后执行的附加命令。语法与ExecStart=相同,只是允许多个命令行,并且命令是一个接一个地串行执行的

如果这些命令中的任何一个(不以“-”为前缀)失败,其余的命令将不会执行,该单元将被视为失败。

 ExecStart=命令仅在所有没有前缀“-”ExecStartPre=命令成功退出后运行。 ExecStartPost =只有在成功调用了ExecStart=中指定的命令后,才运行命令,这由Type=(即,对于Type=simpleType=idle,进程已经启动,对于Type=oneshot,最后一个ExecStart=进程成功退出,对于Type=forking,初始进程成功退出,“READY=1”被发送给Type=notify,或者对于Type=dbusBusName=已被采用) 请注意,ExecStartPre=可能不用于启动长时间运行的进程。所有由通过ExecStartPre=调用的进程分叉的进程将在下一个服务进程运行之前被终止。 请注意,如果在服务完全启动之前,在ExecStartPre =ExecStart=、或ExecStartPost =中指定的任何命令失败(并且没有以“-”作为前缀,请参见上文)或超时,则继续执行在ExecStopPost =中指定的命令,跳过在ExecStop=中指定的命令。 请注意,ExecStartPost =的执行是为了考虑Before=/After=排序约束。

ExecReload=

  ExecReload=kill -HUP $MAINPID

重加载使用,最好为一条命令

ExecStop=

                  可选参数,不写也行;

请注意,ExecStop=中指定的命令仅在服务首次成功启动时执行。如果服务从未启动过,或者启动失败,例如,因为ExecStart=ExecStartPre =ExecStartPost =中指定的任何命令失败(并且没有前缀“-”,见上文)或超时,则不会调用它们。当服务无法正确启动并再次关闭时,使用ExecStopPost =调用命令。还要注意,如果服务成功启动,即使服务中的进程自行终止或被终止,停止操作也始终会执行。停止命令必须准备好处理这种情况。如果systemd知道在调用停止命令时主进程已经退出,那么$MAINPID将被取消设置。 服务重启请求被实现为停止操作,然后是启动操作。这意味着在服务重新启动操作过程中会执行ExecStop=ExecStopPost =命令。 建议将此设置用于与请求干净终止的服务通信的命令。对于事后清理步骤,请使用ExecStopPost =来代替。

RestartSec=

  配置重新启动服务之前的睡眠时间(如重新启动=所配置的)。采用以秒为单位的无单位值,或时间跨度值,如5min 20s。默认为100ms

TimeoutStartSec=

配置等待启动的时间。如果守护程序服务没有在配置的时间内发出启动完成的信号,该服务将被视为失败,并将再次关闭。

RuntimeMaxSec=

                  配置服务运行的最长时间。如果使用了这种方法,并且服务已激活超过指定时间,它将被终止并进入故障状态。请注意,此设置对Type=oneshot服务没有任何影响,因为它们会在激活完成后立即终止。

Restart=

配置当服务进程退出、终止或达到超时时是否应重新启动服务。

如果设置为on-success,则只有在服务进程干净退出时才会重新启动。

选项列表:

                 

 

详情参见官网:

  systemd.service (www.freedesktop.org)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值