0. 始めに
CentOS7で試します.
UbuntuでUpstartを使った例の延長です.
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を使ってさくっと自作コマンドをサービス化してみる