トラフィックサーバー をインストールしてセットアップするスクリプトがあります。
yum install -y trafficserver
systemctl start trafficserver
traffic_line -s proxy.config.url_remap.remap_required -v 0
traffic_line -s proxy.config.reverse_proxy.enabled -v 0
問題は、traffic_line
が次のエラーで失敗することです。
[接続]エラー(main_socket_fd 3):そのようなファイルまたはディレクトリエラーはありません:管理ポートに接続できませんでした。traffic_managerが実行されていることを確認してください
これは、トラフィックサーバーが実際に起動するのを待たずに、systemctl start
がすぐに戻るためです。
systemctl start
に、サービスが開始された後にのみ戻るように指示する方法はありますか?
これが不可能な場合、systemctl start
の後に実行して、サービスが開始されるのを実際に待機できるコマンドはありますか?
これは、トラフィックサーバーが実際に起動するのを待たずに、_
systemctl start
_がすぐに戻るためです。_
systemctl start
_に、サービスが開始された後にのみ戻るように指示する方法はありますか?
_systemctl start
_doesサービスの準備ができるまで待機します(_--no-block
_で呼び出された場合を除く)、サービスはそれを示す必要があるだけです適切に(つまり、_Type=simple
_を使用しないでください)。サービスが準備が整ったときにsystemdに通知しない場合、_systemctl is-active
_、_systemctl show
_などのバリエーションは役立ちません。
コメントで述べたように、最もエレガントな解決策は、ソケットユニットです。 systemdがソケットを開始し、_traffic_line
_がソケットに接続し、systemdがサービスを開始し、_traffic_line
_がサービスがsystemdから継承したファイル記述子の接続の受け入れを開始するまでブロックします。
または、_Type=forking
_(サービスがフォークされ、フォークされたサービスの準備ができるとメインPIDが終了します)または_Type=notify
_(サービスが準備ができるとsd_notify(0, "READY=1")
を呼び出します)を使用できます。
残念ながら、これらのソリューションはすべて、trafficserver
からのサポートが必要です。独自のソケットを割り当てる代わりにsystemdのソケットを使用し、フォークしてメインプロセスで適切に待機するか、_sd_notify
_を呼び出します。サーバーが連携していない場合、systemdはサーバーの準備ができている時期を魔法のように推測できません。:)
trafficserver
のソースコードを少し見たところ、実際には_Type=forking
_をサポートしている可能性があります。サーバーは、専用の_traffic_cop
_コマンドによって起動され、サーバーが起動するまで待機しているようです。そして、いくつかの基本的なテストを実行します(少なくともコードはそのように見えます)。したがって、サービスの種類を変更すると、うまくいく場合があります。
_# /etc/systemd/system/trafficserver.service.d/type-forking.conf
[Service]
Type=forking
_
何度か試してみましたが、ようやく動作しました。
Systemctlのヘルプを調べたところ、is-active
コマンドが見つかりました。
$ systemctl is-active trafficserver
active
したがって、サービスがアクティブになるまで待機するシェルスクリプトを作成しました。
while true; do
if [ $(systemctl is-active trafficserver) == "active" ]; then
break
fi
sleep 1
done
残念ながら、開始/停止でテストすると、このスクリプトは期待どおりに機能しますが、その直後にtraffic_line
コマンドを実行するとまだ同じエラーが発生していました。実際のプロセスが完全に開始する前に(おそらく数ミリ秒)、サービスがアクティブであると報告されていると思います。
だから私は別の方法を試しました。これがサービスの最初の開始であることを知っているので、trafficserverマネージャーのPIDファイルが存在するまで待つことができます。これが私が試したものです:
while [ ! -f /run/trafficserver/manager.lock ]; do
sleep 1
done
同じ問題:trafficserverマネージャーのPIDファイルが書き込まれるとき、マネージャーは実際にはまだ注文を受け取る準備ができていないので、まだエラーが発生していますです。
くそー、私はブラインドを使いたくないsleep
。
そのため、traffic_line
コマンド自体が失敗しないことを確認することにしました。
while ! traffic_line --status &> /dev/null; do
sleep 1
done
そしてこれでうまくいく!
残念ながら、答えは私が使用しているサービス(trafficserver)に非常に固有のものであり、他のサービスには直接適用されません。
この質問に対するより一般的な答えを知っている場合は、遠慮なく共有してください。
私はシェルスクリプトが苦手ですが、ActiveStateとSubStateの両方をテストしたいと思いますactiveおよびrunningをそれぞれ返す場合のプロパティ。
$ systemctl show trafficserver -p SubState,ActiveState
ActiveState=active
SubState=running
その後、スクリプトの2番目の部分を実行できるはずです。