write ahead log

ロールフォワード用

CentOS7でsystemdを使ってgolangで作ったプログラムをデーモン化する

0. 始めに

CentOS7で試します.

UbuntuUpstartを使った例の延長です.

UbuntuでUpstartを使ってプログラムをデーモン化する

1. プログラムを作る

プログラムは前回と同様のサンプルを使います.

挨拶するだけの単純なものです.

package main

import (
        "net/http"
        "fmt"
)

func main() {
        http.HandleFunc("/", helloHandler)
        http.ListenAndServe(":8080", nil)
}

func helloHandler(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello\n")
}

これをhelloというプログラム名でビルドします.

$ go build -o hello

2. Unitファイルを作る(ディレクトリ位置)

CentOS7の場合は下記に作ります. 他のOSも同じかな?調べてませんが.

/etc/systemd/system

実は下記にもUnitファイルがあり, 上記を優先して利用する仕組みだそうです.

/usr/lib/systemd/system

管理者が変更する場合は/etc下へコピーして変更で運用するようです.

3. Unitファイルを作る(作成)

シンプルな例を探して試しました.

これを

/etc/systemd/system/hello.service

として保存します.

;はコメント
#もコメント

[Unit]
# 説明文
Description = Hello Server            

[Service]
# サービス起動時のコマンド
ExecStart = /opt/hello-svr/hello      

# サービス停止コマンド$MAINPIDはメインプロセスのPID参照に利用できる
ExecStop = /bin/kill -HUP $MAINPID    

# サービス再起動コマンド$MAINPIDは上述通り
ExecReload = /bin/kill -HUP $MAINPID && /opt/hello-svr/hello 

# alwaysを指定するとプロセスが死んだ際に常に自動起動する
# デフォルトのnoなら死んだまま
Restart = no                          

# 起動完了の判定条件.
# フォアグラウンドで起動するプログラムはとりあえずsimpleでいい様なので指定.
# forkしてコマンドが終わるタイプはforkingにすればいいらしい
Type = simple                         


[Install]
# 旧来のrunlevelの概念にあたるようです.
# multi-user.target: runlevel:3に相当
# graphical.target: runlevel:5に相当
# 他はman読む方がよさそう
WantedBy = multi-user.target

4. プログラムの配置

当然ですが.

$ sudo cp ~/hello /opt/hello-svr/hello

5. Unitの認識を確認

$ sudo systemctl list-unit-files --type=service | grep hello
hello.service                                 disabled

6. 自動起動をONにする

$ sudo systemctl enable hello

7. サービスを起動する & 確認する

$ sudo systemctl enable hello
Created symlink from /etc/systemd/system/multi-user.target.wants/hello.service to /etc/systemd/system/hello.service.
$ systemctl status hello
● hello.service - Hello Server
   Loaded: loaded (/etc/systemd/system/hello.service; enabled; vendor preset: disabled)
   Active: active (running) since 月 2017-07-17 19:03:03 PDT; 21s ago
 Main PID: 30660 (hello)
   CGroup: /system.slice/hello.service
           └─30660 /opt/hello-svr/hello

8. 動作チェック

$ curl localhost:8080
Hello

9. サービスを再起動する

$ sudo systemctl restart hello

10. サービスを停止する

$ sudo systemctl stop hello

感想

他にも色々出来そうですが, とりあえず今はこれが精一杯.

参考

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

Systemd入門(4) - serviceタイプUnitの設定ファイル

man systemd.unit の訳