Aldebaran

人生最棒的感觉,就是你做到别人说你做不到的事。

0%

自定义systemctl服务脚本

三田寺円

位置和结构

Systemd 默认从目录/etc/systemd/system/读取配置文件。但是,里面存放的大部分文件都是符号链接,指向目录/usr/lib/systemd/system/,真正的配置文件存放在那个目录。

systemctl enable命令用于在上面两个目录之间,建立符号链接关系。如果配置文件里面设置了开机启动,systemctl enable命令相当于激活开机启动。 与之对应的,systemctl disable命令用于在两个目录之间,撤销符号链接关系,相当于撤销开机启动。

systemctl 脚本一般存放在:/usr/lib/systemd , 目录下又有user和system之分

  • /usr/lib/systemd/system # 系统服务,开机不需要登录就能运行的程序(相当于开机自启)
  • /usr/lib/systemd/user # 用户服务,需要登录后才能运行的程序

目录下又存在两种类型的文件:

  • *.service # 服务unit文件
  • *.target # 开机级别unit

内容

服务一般是以.service结尾,一般会分为3部分:[Unit]、[Service]和[Install]。 例如

$ vim /usr/lib/systemd/system/xxx.service

[Unit]   # 主要是服务说明
Description=test   # 简单描述服务
After=network.target    # 描述服务类别,表示本服务需要在network服务启动后在启动
Before=xxx.service      # 表示需要在某些服务启动之前启动,After和Before字段只涉及启动顺序,不涉及依赖关系。

[Service]  # 核心区域
Type=forking     # 表示后台运行模式。
User=user        # 设置服务运行的用户
Group=user       # 设置服务运行的用户组
KillMode=control-group   # 定义systemd如何停止服务
PIDFile=/usr/local/test/test.pid    # 存放PID的绝对路径
Restart=no        # 定义服务进程退出后,systemd的重启方式,默认是不重启
ExecStart=/usr/local/test/bin/startup.sh    # 服务启动命令,命令需要绝对路径
PrivateTmp=true                               # 表示给服务分配独立的临时空间

[Install]   
WantedBy=multi-user.target  # 多用户

字段说明:

  • [Unit]区块通常是配置文件的第一个区块,用来定义 Unit 的元数据,以及配置与其他 Unit 的关系。它的主要字段如下。

      Description:简短描述
      Documentation:文档地址
      Requires:当前 Unit 依赖的其他 Unit,如果它们没有运行,当前 Unit 会启动失败
      Wants:与当前 Unit 配合的其他 Unit,如果它们没有运行,当前 Unit 不会启动失败
      BindsTo:与Requires类似,它指定的 Unit 如果退出,会导致当前 Unit 停止运行
      Before:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之后启动
      After:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之前启动
      Conflicts:这里指定的 Unit 不能与当前 Unit 同时运行
      Condition...:当前 Unit 运行必须满足的条件,否则不会运行
      Assert...:当前 Unit 运行必须满足的条件,否则会报启动失败
    
  • [Service]区块用来 Service 的配置,只有 Service 类型的 Unit 才有这个区块。它的主要字段如下。

    Type的类型有:

      simple(默认):# 以ExecStart字段启动的进程为主进程
      forking:  # ExecStart字段以fork()方式启动,此时父进程将退出,子进程将成为主进程(后台运行)。一般都设置为forking
      oneshot:  # 类似于simple,但只执行一次,systemd会等它执行完,才启动其他服务
      dbus:    # 类似于simple, 但会等待D-Bus信号后启动
      notify:   # 类似于simple, 启动结束后会发出通知信号,然后systemd再启动其他服务
      idle:    # 类似于simple,但是要等到其他任务都执行完,才会启动该服务。
    

    EnvironmentFile:

      指定配置文件,和连词号组合使用,可以避免配置文件不存在的异常。
    

    Environment:

      后面接多个不同的shell变量。 例如:
      Environment=DATA_DIR=/data/elk
      Environment=LOG_DIR=/var/log/elasticsearch
      Environment=PID_DIR=/var/run/elasticsearch
      EnvironmentFile=-/etc/sysconfig/elasticsearch
    
      连词号(-):在所有启动设置之前,添加的变量字段,都可以加上连词号
          表示抑制错误,即发生错误时,不影响其他命令的执行。
          比如`EnviromentFile=-/etc/sysconfig/xxx` 表示即使文件不存在,也不会抛异常
    

    KillMode的类型:

      control-group(默认):# 当前控制组里的所有子进程,都会被杀掉
      process: # 只杀主进程
      mixed:   # 主进程将收到SIGTERM信号,子进程收到SIGKILL信号
      none:    # 没有进程会被杀掉,只是执行服务的stop命令
    

    Restart的类型:

      no(默认值): # 退出后无操作
      on-success:  # 只有正常退出时(退出状态码为0),才会重启
      on-failure:  # 非正常退出时,重启,包括被信号终止和超时等,对于守护进程,推荐用on-failure
      on-abnormal: # 只有被信号终止或超时,才会重启
      on-abort:    # 只有在收到没有捕捉到的信号终止时,才会重启
      on-watchdog: # 超时退出时,才会重启
      always:      # 不管什么退出原因,都会重启
    

    RestartSec字段:

      表示systemd重启服务之前,需要等待的秒数:RestartSec: 30 
    

    各种Exec*字段:

      # Exec* 后面接的命令,仅接受“指令 参数 参数..”格式,不能接受<>|&等特殊字符,很多bash语法也不支持。如果想支持bash语法,需要设置Tyep=oneshot
      ExecStart:    # 启动服务时执行的命令
      ExecReload:   # 重新加载服务 
      ExecStop:     # 停止服务时执行的命令 
      ExecStartPre: # 启动服务前执行的命令 
      ExecStartPost:# 启动服务后执行的命令 
      ExecStopPost: # 停止服务后执行的命令
    
  • [Install]通常是配置文件的最后一个区块,用来定义如何启动,以及是否开机启动。它的主要字段如下。

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

      multi-user.target: # 表示多用户命令行状态,这个设置很重要
      graphical.target:  # 表示图形用户状体,它依赖于multi-user.target
    

    RequiredBy:它的值是一个或多个 Target,当前 Unit 激活时,符号链接会放入/etc/systemd/system目录下面以 Target 名 + .required后缀构成的子目录中
    Alias:当前 Unit 可用于启动的别名
    Also:当前 Unit 激活(enable)时,会被同时激活的其他 Unit

常用的systemctl命令

systemctl daemon-reload    # 重载系统服务

systemctl enable *.service # 设置某服务开机启动
systemctl disable *.service # 禁止某服务开机启动

systemctl list-units # 列出正在运行的 Unit
systemctl list-units --all # 列出所有Unit,包括没有找到配置文件的或者启动失败的
systemctl list-units --all --state=inactive # 列出所有没有运行的 Unit
systemctl list-units --failed # 列出所有加载失败的 Unit
systemctl list-units --type=service # 列出所有正在运行的、类型为 service 的 Unit

systemctl list-unit-files # 命令用于列出所有配置文件
systemctl list-unit-files --type=service # 列出指定类型的配置文件

systemctl start *.service  # 启动某服务
systemctl stop *.service   # 停止某服务
systemctl reload *.service # 重新加载配置
systemctl restart *.service # 重启某服务

systemctl status *.service # 检查服务状态, 服务详细信息
systemctl is-active *.service # 检查服务状态, 仅显示是否 Active