systemd を利用してプロセスをデーモン化する

systemdを利用すれば、プロセスのデーモン化を簡単に行うことができます。

環境

  • ubuntu 16.04
  • ( systemd のシステムであれば使えるはず。)
    • CentOS7 など

デーモン化前

次のようなコマンドをバックグラウンドで実行しているとします。

% cd /var/lib/nem/0.6.79/package/nis
% java -Xms512M -Xmx1G -cp ".:./*:../libs/*" org.nem.deploy.CommonStarter > /var/log/nis.log 2>/var/log/nis.error.log &

これをsystemd でデーモン化します。

systemd でデーモン化する

systemd に必要なファイルを作成します。

/etc/systemd/system/nis-0.6.79.service

[Unit]
Description=NIS
After=syslog.target network.target

[Service]
Type=forking
EnvironmentFile=-/etc/default/nis-0.6.79
WorkingDirectory=/var/lib/nem/
ExecStart=/usr/local/bin/nis-0.6.79-start.sh
ExecStop=/usr/local/bin/nis-0.6.79-stop.sh
User=nem
Group=nem
KillMode=none
Restart = always

[Install]
WantedBy=multi-user.target

Restart = always によって、プロセスが停止したら、自動的に再起動します。

ただ、この段階ではファイルが不足しているので動きません。

  • /etc/default/nis-0.6.79
  • /usr/local/bin/nis-0.6.79-start.sh
  • /usr/local/bin/nis-0.6.79-stop.sh

必要なファイルを作成する

環境変数のためのファイルを作成しておきます。

/etc/default/nis-0.6.79

LOG="/var/log/nem/nis.log"
ERROR_LOG="/var/log/nem/nis.error_log"
RUN_DIR="/var/lib/nem/run/nem"
LOCK_FILE=/var/lib/nem/nis.lock
PID_FILE=/var/lib/nem/run/nem/nis-0.6.79.pid

このファイルに記載した変数はこのサービス内のスクリプトで利用することができます。

起動スクリプトや停止スクリプトで利用します。

起動スクリプトを作成

起動スクリプトを作成します。

/usr/local/bin/nis-0.6.79-start.sh

#!/bin/bash
[ -d $RUN_DIR ] || mkdir -p ${RUN_DIR}
cd /var/lib/nem/0.6.79/package/nis
java -Xms512M -Xmx1G -cp ".:./*:../libs/*" org.nem.deploy.CommonStarter > $LOG 2>$ERROR_LOG &
echo $! > ${PID_FILE}

実行権限・所有権を変更しておきます。

% sudo chown nem. /usr/local/bin/nis-0.6.79-start.sh
% sudo chmod +x /usr/local/bin/nis-0.6.79-start.sh

停止スクリプトを作成

停止スクリプトを作成します。

/usr/local/bin/nis-0.6.79-stop.sh

#!/bin/bash
[ -f ${PID_FILE} ] && kill -9 $(cat ${PID_FILE})
[ -f ${LOCK_FILE} ] && rm ${LOCK_FILE}
[ -f ${PID_FILE} ] && rm ${PID_FILE}

実行権限・所有権を変更しておきます。

$ sudo chown nem. /usr/local/bin/nis-0.6.79-stop.sh
$ sudo chmod +x /usr/local/bin/nis-0.6.79-stop.sh

Serviceとして認識されたか確認する

systemd にservice として認識されたか確認します。

% systemctl list-unit-files --type=service | grep nis
nis-0.6.79.service                         disabled

ここに表示されたら、認識されていることがわかります。

もし表示されなかったら、なにかおかしいのでエラー文などを参考に修正してみてください。

サーバ起動時に自動起動する

サーバ起動時に自動起動するようにします。

# 自動起動on
$ sudo systemctl enable nis-0.6.79
$ systemctl list-unit-files --type=service | grep nis
nis-0.6.79.service                         enabled

起動 / 確認 / 停止

#  起動
$ sudo systemctl start nis-0.6.79

# 確認
$ sudo systemctl status nis-0.6.79

● nis-0.6.79.service - NIS
   Loaded: loaded (/etc/systemd/system/nis-0.6.79.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2016-10-17 06:25:05 JST; 1 day 5h ago
  Process: 30714 ExecStop=/usr/local/bin/nis-0.6.79-stop.sh (code=exited, status=0/SUCCESS)
  Process: 30720 ExecStart=/usr/local/bin/nis-0.6.79-start.sh (code=exited, status=0/SUCCESS)
 Main PID: 13771
    Tasks: 43
   Memory: 1.1G
      CPU: 19min 49.692s
   CGroup: /system.slice/nis-0.6.79.service
           └─30721 java -Xms512M -Xmx1G -cp .:./*:../libs/* org.nem.deploy.CommonStarter

#  起動
$ sudo systemctl stop nis-0.6.79

OSを再起動して、サービスが自動起動するか確認

もしサービスインする前でしたら、OS を再起動して、サービスが自動起動するか確認します。

# 再起動
$ reboot

起動していたらokです

# 確認
$ sudo systemctl status nis-0.6.79

以上です。

参考

Systemd入門(1) - Unitの概念を理解する - めもめも

いまさらだけどsystemdに入門した - 雑なメモ

Systemdを使ってさくっと自作コマンドをサービス化してみる - Qiita