Edited at

SystemdのServiceで複数のプロセスを起動する


環境

Ubuntu Server 18.04


はじめに

あるrubyプログラムを引数により別な挙動をさせたい場合があります。

これを1つのserviceに登録する、というものです。


動かすrubyプログラム

whileで延々と時刻とhelloを書き込むだけのrubyプログラムですが、引数により出力するファイルが違います。

/home/hoge/ruby/hello.rbとし、実行権限を与えます。


/home/hoge/ruby/hello.rb

#!/usr/bin/env ruby

while true
f = File.open("./out#{ARGV[0]}.txt",'a')
f.puts Time.now.to_s + " hello"
f.close
sleep 1
end

$ chmod 0755 /home/hoge/ruby/hello.rb

これに引数をつけて実行すると、out引数.txtに時刻とhelloが書き込まれます。


/home/hoge/ruby/

./hello.rb 1



out1.txt

2018-09-14 23:10:13 +0900 hello

2018-09-14 23:10:14 +0900 hello
2018-09-14 23:10:15 +0900 hello
2018-09-14 23:10:16 +0900 hello
2018-09-14 23:10:17 +0900 hello


シェルプログラムで並行処理させるには

これに1〜4の引数を与えて、並列プロセスとしてシェルで実行させます。

/home/hoge/bin/hello.sh

以下はダメな例。ただ順番に書いただけでは順列に処理されるだけです。


hello.sh

#!/bin/bash

cd /home/hoge/ruby/
./hello.rb 1
./hello.rb 2
./hello.rb 3
./hello.rb 4

並列プロセスとして処理させたい場合は”&”をつけます。

参考:バックグラウンドプロセス


hello.sh

#!/bin/bash

cd /home/hoge/ruby/
./hello.rb 1 &
./hello.rb 2 &
./hello.rb 3 &
./hello.rb 4 &

これにも実行権限をつけます。

$ chmod 0755 /home/hoge/bin/hello.sh


systemdに登録

「/etc/systemd/system」にUnit定義ファイルを作ります。

WorkingDirectoryを指定してやらないと、rubyの中で相対パスで出力しているため、out*.txtが「/」配下にできてしまいます。

Typeはsimpleではなくforkingで。

wiki=>forkとは

forkingにすることで、個々のrubyプログラムにプロセスIDが割り振られます。

Installセクションが無いと、後述のenableで失敗します。

[Unit]

Description = hello daemon

[Service]
WorkingDirectory = /home/hoge/ruby
ExecStart = /home/hoge/bin/hello.sh
Restart = always
Type = forking

[Install]
WantedBy = multi-user.target

Unit定義ファイルができたら、下記コマンドでsystemctlに読み込みます。

$ sudo systemctl daemon-reload

確認。この段階ではまだ「disabled」です。

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

hello.service disabled


起動

下記コマンドでhello をenableします。

$ sudo systemctl enable hello

sudo service hello start


status

サービス起動しているかstatusでチェック

$ sudo service hello status

● hello.service - hello daemon
Loaded: loaded (/etc/systemd/system/hello.service; enabled; vendor preset: en
Active: active (running) since Sat 2018-09-15 01:24:49 JST; 4min 26s ago
Main PID: 5837 (code=exited, status=0/SUCCESS)
Tasks: 8 (limit: 1104)
CGroup: /system.slice/hello.service
├─6079 ruby ./hello.rb 1
├─6080 ruby ./hello.rb 2
├─6081 ruby ./hello.rb 3
└─6082 ruby ./hello.rb 4

Sep 15 01:24:49 parallesubuntu1804sv systemd[1]: Starting hello daemon...
Sep 15 01:24:49 parallesubuntu1804sv systemd[1]: Started hello daemon.

ちゃんとserviceで複数プロセスが起動されています。


参考

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

シェルスクリプトで単純に並列実行・直列実行を行う