Ubuntuの下のinit.dスクリプトの配列を決定する方法
質問
私は私が正しい順序で起動する必要があるいくつかのサーバーや他のデーモンを持っています。
私はスケルトンスクリプトからのinit.dスクリプトを作成している、と番号ネーミングシステムを使用して適切な順序で起動するためにそれらをインストールすることができますが、いくつかの問題が残ってます:
1台のサーバー(「サーバA」)は、データベース接続を初期化した後、ソケットをリッスンする必要があります。 別のサーバー(「サーバB」)は、そのソケットに接続する必要がある、と前にプロセスがまだ聴いていない場合、接続は失敗します。サーバAは、リスニング開始されるまで終了からサーバAのためのinit.dスクリプトを防止する方法はありますか?サーバAの初期化が終了するまで、サーバBのinitが起動しません。
今、セットアップは、それが成功するまでサーバBは、単に接続を再試行させることによって動作しますが、そのアプローチは壊れやすいようです。私は、シーケンシングを強制する方法のより多くの決定論的理解をしたいと思います。
解決
はい、これは私が答えるのです私の質問ですが、私はこの技術が有用であること、および同様の問題に苦しんで他の誰のために共有していた。
私は、ソケットまたはポートを待っているに非常に有用であることがsocatに関するを発見しました。以下のようなinit.dスクリプトます:
case “$1″ in
start)
echo '--benign phrase' | socat - UNIX-CONNECT:/path/to/socket,retry=10,intervall=1
;;
ソケットが書き込み可能になるまで待機します、その後、戻ります。それが終了するまで、それは大きい番号のinit.dスクリプトのブロックの実行がそこにはデーモン化関係はありませんので、。
などウェイタースクリプトを使用すると、ブートシーケンスを遅らせるため、非最適ですが、「睡眠n」は、スクリプト内のステートメントを散水する非常に壊れやすいアプローチから大きな改善されます。
他のヒント
私はそれが壊れているとは思わない - それが壊れてはならないだろうどこ少なくとも私は、シナリオの考えることができます。 5秒とその悪くない、全くの再試行時間を持っています。そのKISSのアプローチと、あなたが理解していない任意のコーナーケースがありません。
は、同期分散環境を得ることは心の弱い人のためではなく、あなたの例ではそのやり過ぎています。
あなたのアプローチでは、いくつかの自信を与えるために、私は、彼らがウェブ農場上に分散手書きの複雑なサーバー・プロセスの数十を私にデータベースサーバが消滅してもすべての悲しみを与えられていない場合、またはネットワークたことがないていることを伝えることができトランクは、データベースが戻ってくるまで、彼らは単に劣化モードで実行し続けるなどをダウンした。
、あなたはそのソケットのポーリングループを構築することができます。そこbashでこれを行うための簡単な方法かもしれないが、それはのようになります:
for i in 1 2 3 4 5; do
if [ -e '/var/run/myserver.sock' ]; then
break
fi
done
別の解決策は、それがリスニングソケットを開いているまで、あなたのサーバがデーモンではない持っていることです。その方法は、initスクリプトは、ソケットが利用可能である保証プロセスdaemonizesまで一時停止されます。
もちろん、これはむしろ、いくつかの他の手段を通じてよりも、デーモン化自体をやって、あなたのアプリケーションに依存します。 ( "は/ usr / binに/ MYSERVER&" など。)
の更新:の
また、あなたが今やっていることは、すべてのシステム-Vスタイルのinitである、ということに注意してください。 Ubuntuは実際にイベントベースのシステムではなく、スクリプトの順序で成り上がりを、使用しています。あなたは第二のサーバの起動をトリガする、成り上がりの仕事ではなく、システム-Vのinitスクリプトを使用して、サーバーからカスタム成り上がりイベントを発射するために選ぶことができます。
例を有するのスタートガイド一番下にあるこれの。あなたの最初のサーバーでの時間の右の時点で、「APIの方法があるかどうかは知りませんが、それは単に 『システム(』 / binに/ myeventを発するinitctl)」の問題である可能性があります。より多くの成り上がり経験を持つ他の誰かがより良い/さらに詳しく説明することができるかもしれない。