デフォルトでは、systemdがサービスを再起動するように要求された場合は、最初のプロセスを停止してから2番目のプロセスを開始するため、タイムラインは次のようになります。
PROCESS A
--------[stopped]
[started]--------
PROCESS B
サービスのダウンタイムに時間を費やすことはできませんが、両方のサービスを一緒に開始するのは大丈夫ですので、タイムラインを次のように表示したいと思います。
PROCESS A
------------------[stopped]
[started]------------------
PROCESS B
どうすればいいですか?
答え1
解決策を提案します。サービスの複数のインスタンスを作成して最初のインスタンスを停止する前に、2番目のインスタンスを起動します。
たとえば、次の名前のユニットファイルを設定します(必須)。/etc/systemd/system/[email protected]
@
[Install]
# for example
WantedBy=multi-user.target
[Unit]
# for example
Description=mymonitor %i
[Service]
# for example; the %i may not be useful in your case
ExecStart=/path/to/monitor %i
それを発見:
sudo systemctl daemon-reload
活性化:
sudo systemctl enable mymonitor@thisone
...そして起動時にインスタンス名 "thisone"でモニターを起動します。
サービスを再起動したい場合は、スクリプトを使用して簡単なテストを実行できます。
#!/bin/sh
if systemctl is-active mymonitor@thisone > /dev/null
then
systemctl start mymonitor@thatone &&
systemctl stop mymonitor@thisone
else if systemctl is-active mymonitor@thatone
systemctl start mymonitor@thisone &&
systemctl stop mymonitor@thatone
else
echo Houston, we have a problem
# or perhaps you want to start, with: systemctl start mymonitor@thisone
fi
開始と停止の間にさらに重複が必要な場合は、次のようにビルドしてください。
# ...
if systemctl start mymonitor@thisone
then
sleep 7
systemctl stop mymonitor@thatone
fi
# ...
答え2
ロードバランサー、ファイアウォールルール、またはトラフィックの再ルーティングなしで1つのノードでこれを直接達成することは不可能だと思います。確かにsystemdの範囲外です。
その理由は、サービスがリッスンポートを占めるためです。ダウンタイムを排除するために、クライアントは存在しないポートまたはサービスのためにダウンポートに接続してはいけません。ただし、同じポートとIPで同時にProcess A
実行することはできませんProcess B
。
ダウンタイムを排除するには、古いポート以外のポートで新しいプロセスを開始し、ファイアウォールルールやロードバランサーなどの機能を使用して古いポートから新しいポートにトラフィックをリダイレクトする必要があります。その後、古いクライアントの接続が失われるのを待つ必要があります。その後、古いサービスをオフにすることができます。
これを達成するための「一般的な」方法は、ロードバランサーの後に2つのノード(2つのサーバー)を使用することです。この場合、ロードバランサーを一時的に再構成してノードを再始動して別のノードを指すように、再始動が完了した後に再構成することができます。
これはsystemdの範囲をはるかに超えています。ファイアウォールを使用してこのプロセスを自動化し、他のポートを使用するようにサービスを自動的に再構成したい場合は、これを達成するための複雑なスクリプトセットを構築し、reload
それをカスタムオプションにリンクできます。