使用systemd来构建你的服务

systemd是什么

Systemd 服务是一种以 .service 结尾的单元(unit)配置文件,用于控制由Systemd 控制或监视的进程。简单说,用于后台以守护精灵(daemon)的形式运行程序。linux

为何要使用systemd

  1. service文件编写简单易用
  2. 能够自动维持进程存活(强大的功能,能够取代PM2)
  3. 自动收集进程输出的输出

systemd主要命令

能够看到systemd以字母d结尾,根据linux惯用规则,能够判断该进程为守护进程,能够经过systemctl与之交互。git

systemctl start redis.service #启动服务
systemctl stop redis.service #中止服务
systemctl restart redis.service #重启服务
systemctl enable redis.service #将redis设置为开机启动

编写systemd

systmd service文件通常放在/etc/systemd/system/文件夹中。redis

systemd service文件是结构化的,如下给出一份笔者经常使用的清单。bash

[Unit]
Description=Git Auto Update Hook Service
After=network.target

[Service]
Type=simple
ExecStart=/root/src/git-hookd/git-hookd
Restart=always
[Install]
WantedBy=multi-user.target

拿以前写过的init.d的脚本对比一下网络

#!/bin/bash
### BEGIN INIT INFO
# Provides:          xialeistudio
# Required-Start:    $network
# Required-Stop:     $local_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: test service
# Description:       test service
### END INIT INFO
PROG="testd"
PROG_PATH="/root/apps/testd"
PROG_ARGS="-u xialei"
PID_PATH="/var/run/"

start() {
        if [ -e "$PID_PATH/$PROG.pid" ]; then
                echo "Error! $PROG is running!" 2>&1
                exit 1
        else
                $PROG_PATH/$PROG $PROG_ARGS 2>&1 > "/var/log/$PROG.log" &
                pid=`ps ax|grep testd|awk '{print $2}'|head -n 1`
                echo "$PROG started"
                echo $pid > "$PID_PATH/$PROG.pid"
        fi      
}

stop() {
        if [ -e "$PID_PATH/$PROG.pid" ]; then
                pid=`ps ax|grep testd|awk '{print $2}'|head -n 1`
                kill $pid
        
                rm -rf "$PID_PATH/$PROG.pid"
                echo "$PROG $pid killed"
        else
                echo "Error! $PROG not running!" 2>&1
                exit 1
        fi
}

if [ "$(id -u)" != "0" ]; then
        echo "Please run as root!" 2>&1
        exit 1
fi

case "$1" in
    start)
                start
                exit 0
        ;;
        stop)
                stop
                exit 0
        ;;
        reload|restart)
                stop
                start
                exit 0
        ;;
        **)
                echo "Usage: $0 {start|stop|reload}" 2>&1
                exit 1
        ;;
esac

能够看到init.d脚本实在是太原始了,systemd取代init.d指日可待app

systemd service文件说明

service文件由 Unit, Service, Install 三部分组成ide

Unit

全部引导过程当中systemd要控制的文件/设备/程序等等都称为一个单元。ui

  • Description: 服务描述
  • Wants: 本单元启动成功,则会启动此字段定义的单元,若是Wants定义的单元启动失败,对本单元无影响
  • Requires:本单元启动成功,则会启动此字段定义的单元,若是Requires定义的单元启动失败,本单元也失败。该字段没法控制前后顺序,若是Requires定义的单元未启动完成就启动本单元,那么一个都启动不了,不建议用这个字段
  • OnFailure: 本单元若是启动失败,则启动该字段定义的单元
  • Before/After:指定本单元的启动顺序

本例中只须要依赖网络单元便可rest

Service

服务本体定义:code

  • Type 启动类型
  • ExecStart 启动服务的命令
  • ExecStop 中止服务的命令(通常不写)
  • Restart 重启规则
  • RemainAfterExit 即便没有进程,也认为服务启动成功

Type 启动类型有如下几种:

+ simple: 默认类型,启动的进程将成为服务进程。
+ forking:标准Unix Daemon进程。本进程启动后会经过系统调用fork,把必要的通讯频道都设置好以后父进程退出,留下守护精灵的子进程。(也就是说你本身来将进程变成daemon进程)
+ oneshot:一次性命令。该服务运行完毕后没有进程,因此须要配合RemainAfterExit。

Restart 重启规则有如下几种:

+ no(默认值):退出后不会重启
+ always:无论是什么退出缘由,老是重启
+ on-success:只有正常退出时(退出状态码为0),才会重启
+ on-failure:非正常退出时(退出状态码非0),包括被信号终止和超时,才会重启
+ on-abnormal:只有被信号终止和超时,才会重启
+ on-abort:只有在收到没有捕捉到的信号终止时,才会重启
+ on-watchdog:超时退出,才会重启

Install

systemd装载规则定义

  • WantedBy 将被谁装载,本例中使用multi-user.target,最终服务将经过软连接到/etc/systemd/system/multi-user.target.wants目录
  • Alias 服务别名,能够经过 systemctl 服务别名 restart 之类的来操做

写在最后

是时候经过systemd改写init.d的服务了,有必要的话能够连pm2守护的进程都交给systemd来处理。

相关文章
相关标签/搜索