他のサービス(activemq)が「アクティブ」である必要があり、接続を開始する前に接続をリッスンするために必要なすべてのポートを持ついくつかのサービス(A、B、C)があります。サービスBとCはAに依存します。これは再びactivemqとリッスンポート(特にポート61616)に依存します。
私が経験している問題は、activemqがすべてのポートを開く前にsystemdがactivemqサービスを「アクティブ」としてマークすることです。だから私のサービス(A)が起動して終了します。
私が試したこと:
set:Restart = on-success(または常に)動作しますが、すべてのサービス(ABC)に対してこれを行う必要があります。私はこのルールを適用したくありません。
仕組みは、サービスAに以下を追加することです。
ExecStartPre=/bin/sleep 30
これにより、サービスAが正しく起動されるため、BとCは追加の構成を必要としません(すべてのサービスA、B、Cに対して対応する「After =」および「Requires =」設定を除く)。しかし、私はこれが正確でクリーンな解決策だとは思わない。
[サービス]で他のオプションも試しましたが、Type = forkなどの何も機能しませんでした。
私が望むもの:
- すべてのポート(4つあり)または少なくとも最後のポート(問題を引き起こすポート)でリッスンしている場合にのみ、activemqサービスを「アクティブ」としてマークするようにsystemdに指示します。 61616または
- ポート61616(ある種のRequire = tcp / 61616など)でリッスンした後にのみサービスAを開始してください。
activemq.service ファイルは次のとおりです。
[Unit]
Description=Activemq Servoce
After=local-fs.target
After=network.target
[Service]
Type=simple
SuccessExitStatus=0 143
ExecStart=/usr/bin/activemq console
User=activemq
Group=activemq
Restart=always
PrivateTmp=true
[Install]
WantedBy=multi-user.target
答え1
ベース:
Systemdは、activemqがすべてのポートを開くまで、activemqサービスを「アクティブ」としてマークします。
そして:
[サービスA]は、受信にactivemqとそのポート(具体的にはポート61616)を使用します。
...systemdのサービス状態の理解を「プロセス実行中」から「プロセス実行中」に変更できます。そしてポートが開いています」ExecStartPostオプションこの使用中のループは、オペレーティングシステムがポートがリスニングされていることを示すまで待機します。
一例:
ExecStartPost=/usr/bin/timeout 30 sh -c 'while ! ss -H -t -l -n sport = :61616 | grep -q "^LISTEN.*:61616"; do sleep 1; done'
これは、ExecStartの後に実行するコマンドをsystemdに提供します。このコマンドは、timeout
デフォルトのアプリケーションが正常に起動せず、30秒以内にポートでリッスンできない場合にエラーを停止するためのものです。このコマンドは、リッスンしているポートをテストするtimeout
単純なシェルループをラップします。sh -c ...
シェルループ自体は条件が真になるまで実行され、ss ... | grep ...
各テスト間に1秒かかります。sleep
これss
注文する次のオプションを使用できます。
-H
- ヘッダーの抑制(このオプションは必須ではありませんが、ノイズを除去したい)-t
- TCPソケットのみを表示-l
- リスニングソケットのみを表示-n
- サービス番号を名前として解釈しないでください -grep
後で使用するために番号のままにしてください。sport = :61616
- ソースポートが61616のエントリに出力を制限するフィルタ
その後、コマンドはgrep
"LISTEN" で始まり、その後に文字列 ":61616" が続く行を探します。これは、デフォルトアプリケーションがそのポートでリッスンを開始したことを示します。この-q
フラグはgrepに成功または失敗のみを報告し、出力をエクスポートしないように指示します。なぜなら、我々は行が存在するかどうかに興味があるからです。
デフォルトのアプリケーションの起動中に、systemdはExecStartPostコマンドが終了するまで「start-post」ステータスを表示します。アプリケーションが正常に起動し、30秒以内にポートが開かれると、systemdはステータスを「アクティブ(実行中)」に更新します。エラーが発生した場合、systemdは(例では)プロセス全体を再開しますRestart=always
が、そうでない場合は「失敗(結果:終了コード)」を報告し、終了コード「(code = exited、status = 124)」を使用してExecStartPostコマンドを隠すします。 、コマンドがタイムアウトし、基本プロセスが終了することを示します。