• 如何编写一个Systemd Service


    小述

    想要把自己的服务使用systemd管理需要书写*.service文件,如服务名xxx.service,下面我们介绍一下*.service文件里面具体的内容。

    避坑前置

    当我们的文件所有操作进行完成后,为了能使我们的服务在systemd管理下生效需要进行以下操作

    systemctl daemon-reload#重新加载某个服务的配置文件,如果新安装了一个服务,归属于 systemctl 管理,要是新服务的服务程序配置文件生效,需重新加载。

    systemd 介绍

    systemd是目前Linux系统上主要的系统守护进程管理工具,由于init一方面对于进程的管理是串行化的,容易出现阻塞情况,另一方面init也仅仅是执行启动脚本,并不能对服务本身进行更多的管理。所以从CentOS 7开始也由systemd取代了init作为默认的系统进程管理工具。

    systemd所管理的所有系统资源都称作Unit,通过systemd命令集可以方便的对这些Unit进行管理。比如systemctl、hostnamectl、timedatectl、localctl等命令,这些命令虽然改写了init时代用户的命令使用习惯(不再使用chkconfig、service等命令),但确实也提供了很大的便捷性。

    systemd 是内核启动后的第一个用户进程,PID 为1,是所有其它用户进程的父进程。

    systemd 特点

    • 最新系统都采用systemd管理(RedHat7,CentOS7,Ubuntu15…)

    • CentOS7 支持开机并行启动服务,显著提高开机启动效率

    • CentOS7关机只关闭正在运行的服务,而CentOS6,全部都关闭一次。

    • CentOS7服务的启动与停止不再使用脚本进行管理,也就是/etc/init.d下不在有脚本。

    • CentOS7使用systemd解决原有模式缺陷,比如原有service不会关闭程序产生的子进程

    systemd 语法

    systemctl   [command]    [unit](配置的应用名称)
     
    command可选项· 
    start:启动指定的unit         systemctl start nginx
    stop:关闭指定的unit          systemctl stop nginx
    restart:重启指定unit         systemctl restart nginx
    reload:重载指定unit          systemctl reload nginx
    enable:系统开机时自动启动指定unit,前提是配置文件中有相关配置 systemctl enable nginx
    disable:开机时不自动运行指定unit  systemctl disable nginx
    status:查看指定unit当前运行状态   systemctl status nginx

    systemd 配置文件说明

    /etc/systemd/system/*  #系统管理员安装的单元, 优先级更高
     
    /run/systemd/system/*  #运行时动态创建unit文件的目录
     
    /usr/lib/systemd/system/* #系统或第三方软件安装时添加的配置文件。存放systemctl脚本

    CentOS 7的服务systemctl脚本存放在:/usr/lib/systemd/,有系统 system 和用户 user 之分, 即:/usr/lib/systemd/system 和 /usr/lib/systemd/user

    • 每一个 Unit 都需要有一个配置文件用于告知 systemd 对于服务的管理方式
    • 配置文件存放于/usr/lib/systemd/system/ ,设置开机启动后会在 /etc/systemd/system 目录建立软链接文件
    • 每个Unit的配置文件配置默认后缀名为.service
    • 在 /usr/lib/systemd/system/ 目录中分为 system 和 user 两个目录,一般将开机不登陆就能运行的程序存在系统服务里,也就是 /usr/lib/systemd/system
    • 配置文件使用方括号分成了多个部分,并且区分大小写

    编写服务配置 

    每一个服务以.service结尾,一般会分为3部分:[Unit][Service][Install]

    • [Unit]:记录unit文件的通用信息。

    • [Service]:记录Service的信息

    • [Install]:安装信息。

    [Unit]

    主要是对这个服务的说明,内容, 文档介绍以及对一些依赖服务定义

    • Description : 服务的简单描述
    • Documentation : 服务文档
    • Requires:当前 Unit 依赖的其他 Unit,如果它们没有运行,当前 Unit 会启动失败
    • Wants:与当前 Unit 需要的其他 Unit,如果它们没有运行,当前 Unit 不会启动失败
    • BindsTo与当前 Unit 绑定的其他 Unit,如果它们退出,会导致当前 Unit 停止运行
    • Before:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之后启动
    • After:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之前启动
    • Conflicts:这里指定的 Unit 不能与当前 Unit 同时运行
    • Condition…:当前 Unit 运行必须满足的条件,否则不会运行
    • Assert…:当前 Unit 运行必须满足的条件,否则会报启动失败

    1. [Unit]
    2. Description=Protect ARP list
    3. Wants=network-online.target
    4. After=network.target
    • 其中network.target代表有网路,network-online.target代表一个连通着的网络。

     [service]

    服务本体

    在定义完了 Systemd 用来识别服务的单元后,我们来定义服务本体。基本的用法如下:


    Type:服务的类型,各种类型的区别如下所示

    • simple:默认,这是最简单的服务类型。意思就是说启动的程序就是主体程序,这个程序要是退出那么一切皆休。
    • forking:标准 Unix Daemon 使用的启动方式。启动程序后会调用 fork() 函数,把必要的通信频道都设置好之后父进程退出,留下守护精灵的子进程。(以 fork 方式从父进程创建子进程,创建后父进程会立即退出)
    • oneshot:systemd中的Type=oneshot服务描述了这一选项适用于只执行一项任务、随后立即退出的服务。可能需要同时设置 RemainAfterExit=yes 使得 systemd 在服务进程退出之后仍然认为服务处于激活状态。
    • dbus:这个程序启动时需要获取一块 DBus 空间,所以需要和 BusName= 一起用。只有它成功获得了 DBus 空间,依赖它的程序才会被启动。
    • notify: 这个程序在启动完成后会通过 sd_notify 发送一个通知消息。所以还需要配合 NotifyAccess 来让 Systemd 接收消息,后者有三个级别:none,所有消息都忽略掉; main,只接受我们程序的主进程发过去的消息; all,我们程序的所有进程发过去的消息都算。NotifyAccess 要是不写的话默认是 main。(当前服务启动完毕,会通知Systemd,再继续往下执行)

    ExecStart

    启动当前服务的命令

    ExecStartPre

    启动当前服务之前执行的命令

    ExecStartPost

    启动当前服务之后执行的命令

    ExecReload

    重启当前服务时执行的命令

    ExecStop

    停止当前服务时执行的命令

    ExecStopPost

    停止当其服务之后执行的命令

    RestartSec

    自动重启当前服务间隔的秒数

    Restart

    定义何种情况 Systemd 会自动重启当前服务,可能的值包括always(总是重启)、on-success、on-failure、on-abnormal、on-abort、on-watchdog

    • no(默认值):退出后不会重启;
    • always:不管是什么退出原因,总是重启;
    • on-success:只有正常退出时(退出状态码为0),才会重启;
    • on-failure:非正常退出时(退出状态码非0),包括被信号终止和超时,才会重启;
    • on-abnormal:只有被信号终止和超时,才会重启;
    • on-abort:只有在收到没有捕捉到的信号终止时,才会重启;
    • on-watchdog:超时退出,才会重启,如ssh服务设置为on-failure,表示任何意外的失败,就将重启sshd。如果sshd正常停止(比如执行systemctl stop命令),它就不会重启。

    TimeoutSec

    定义 Systemd 停止当前服务之前等待的秒数

    RemainAfterExit

    值为yes或no,表示进程退出以后,服务仍然保持执行。这样的话,一旦使用systemctl stop命令停止服务,ExecStop指定的命令就会执行

    通常和type=oneshot配合使用

    Environment

    指定环境变量

    EnvironmentFile

    指定当前服务的环境参数文件,该文件的key=value键值对,可以用$key的形式,在当前配置文件中获取

    User

    指定用户运行

    Group

    指定用户组运行

    WorkingDirectory

    进程工作目录,也就是说在执行前会先切换到这个目录

    [Install]

    服务安装的相关设置,一般可设置为多用户的

    • WantedBy:它的值是一个或多个 Target,当前 Unit 激活时(enable)符号链接会放入/etc/systemd/system目录下面以 Target 名 + .wants后缀构成的子目录中

    • RequiredBy:它的值是一个或多个 Target,当前 Unit 激活时,符号链接会放入/etc/systemd/system目录下面以 Target 名 + .required后缀构成的子目录中

    • Alias:当前 Unit 可用于启动的别名(比如Master.service文件名字,正常 systemctl status Master.service,设置别名叫Alias=nm,那你就可以systemctl status nm.service 查看实际是Master.service的服务了)

    • Also:当前 Unit 激活(enable)时,会被同时激活的其他 Unit

    • Linux 缓和的执行进程关闭,然后重启。在对配置文件修改后需要重启进程时可发送此信号。

    *.target级别

    0runlevel0.target,poweroff.target关闭系统。
    1runlevel1.target,rescue.target进入救援模式。
    2runlevel2.target,multi-user.target进入非图形界面的多用户方式。
    3runlevel3.target,multi-user.target进入非图形界面的多用户方式。
    4runlevel4.target,multi-user.target进入非图形界面的多用户方式。
    5runlevel5.target,graphical.target进入图形界面的多用户方式。
    6runlevel6.target,reboot.target重启系统。

    如:WantedBy=multi-user.target 在 multi-user.target 启用时,我们的服务也就会被启用了。

    完整实例

    [Unit]

    Description=Protect ARP list

    Wants=network-online.target

    After=network.target

    [Service]

    Type=oneshot

    RemainAfterExit=yes

    ExecStart=/sbin/arp -f /etc/ip-mac

    ExecReload=/sbin/arp -f /etc/ip-mac

    ExecStop=/sbin/arp -d -a

    [Install]

    WantedBy=multi-user.target

  • 相关阅读:
    现代图片性能优化及体验优化指南 - 图片资源的容错及可访问性处理
    MATLAB运算符
    MATLAB如何将k线图设置为经典红绿配色?
    MyCat 管理及监控
    没钱,没人,没经验?传统制造型企业如何用无代码实现转型
    快排,代码思路详解
    【安卓基础1】初识Android
    《庆余年》角色穿越高考:谁将笑傲现代考场?
    基于quartz的定时任务动态启停实现分析(人人平台为例)
    深入理解Java CompletableFuture并发编程模型
  • 原文地址:https://blog.csdn.net/sunboylife/article/details/126807577