SysVでは、条件を使用して、データベースが稼働する前にアプリケーションが起動しないようにすることができます。私はinitスクリプトに待機する時間を与え、データベースサービスがまだ利用できない場合は、しばらくしてから最後にあきらめます。
start() {
local exec=/path/to/exec
local tries=1
[ -x $exec ] || exit 5
echo -n $"Starting $prog: "
#check communication to database
if ! [ 2>/dev/null : < /dev/tcp/$dbHost/$dbPort ]
then
while ! [ 2>/dev/null : < /dev/tcp/$dbHost/$dbPort ] && [ ! $tries -ge 5 ]
do
>&2 echo -e "Could not connect to the database on $dbHost\nWaiting 10 seconds to check database status, attempt $tries"
sleep 10
((tries++))
done
sleep 10
if ! (: < /dev/tcp/$dbHost/$dbPort ) 2>/dev/null
then
>&2 echo -e "Could not connect to the database on $dbHost aborting startup of $exec"
exit 1
fi
fi
私はドキュメントとグーグルで同様のシナリオを探していましたが、ローカルサービスを参照していないものは何も見つかりませんでした。
systemdサービスのドキュメントでExecStartPreを確認しましたか?
データベーステストをスクリプトに入れて、exit 0
成功した場合、exit 1
失敗した場合、ExecStartPre
で実行します。次に、ExecStart
を使用してアプリケーションを起動します。
@GracefulRestartの答えは、データベースの可用性に応じて1つのサービスしかない場合に最適です。ただし、この要件を持つサービスが複数ある場合は、すべてのサービスがRequires=
依存関係を持つことができるワンショットサービスを作成します。
/ etc/systemd/system/portopen @ .service
[Unit]
Description=Checks database availability on %I
After=network.target
Requires=network.target
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/path/to/portopen.sh %I
[Install]
WantedBy=default.target
/ path/to/portopen.sh
#!/bin/bash
dbhost=${1:-localhost}
dbport=${2:-5678}
maxtries=${3:-5}
wait=${4:-10}
tries=1
# Check communication to database
while ! [ 2>/dev/null : < /dev/tcp/$dbhost/$dbport ]; do
echo "Unable to connect to database on $dbhost TCP/$dbport (attempt $tries): retrying in $wait seconds" >&2
(( tries++ ))
if [[ $tries -le $maxtries ]]; then
sleep $wait
else
echo "Unable to connect to database on $dbhost TCP/$dbport: aborting"
exit 1
fi
done
データベースサーバーを変更または追加したり、ポートを変更したり、サービスレベルでの再試行回数を変更したりする場合に備えて、スクリプトをもう少し柔軟にしました。それが必要ない場合は、サービスportopen.service
を呼び出して%I
の部分を削除してください。
データベースサーバーがfoobar
上にあり、データベースアプリケーションがfoobarapp.service
上で実行されているとします。 foobarapp.service
に次の変更を加えます。
# systemctl edit foobarapp.service
[エディタ内]
[Unit]
[email protected]
[email protected]
次に、systemd
をリロードして、チェックを開始して有効にします。
# systemctl daemon-reload
# systemctl enable [email protected]
その後、いつでもfoobarapp.service
を再起動できます。 [email protected]
が正常に戻った場合にのみ開始されます。
まだ存在しない場合、データベースアプリケーションサービスfoobarapp.service
は次のようになります。
/ etc/systemd/system/foobarapp.service
[Unit]
Description=Foobar database application
# Add any other dependencies here
[email protected]
[email protected]
[Service]
# If it is a daemon, use "forking" instead
Type=simple
ExecStart=/path/to/exec
[Install]
WantedBy=default.target