使用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來處理。

相關文章
相關標籤/搜索