web-dev-qa-db-ja.com

/ etc / service(runit)の起動スクリプトがデーモンで動作していません

/etc/serviceで開始し、runitを使用しているスクリプトの問題に直面しています。

/etc/service/myApp/runのスクリプトは次のようになります。

#!/bin/bash
cd /src
forever -l forever.log -o out.log -e err.log -a start bin/www

Forever が行うことは、スクリプトをデーモンとして実行することです。しかし、これを行うと、runitは私のサービスが終了し、/etc/service/myApp/runを何度も何度も実行していると考えているようです...

また、これをデーモンとして実行しようとしましたnotフォアグラウンドで正常に動作しますが、それでも問題があります。最終的にフォアグラウンドプロセスをシャットダウンする、ある時点でサーバーに送信するclean-shutdownコマンドがあり、再起動を望んでいません。しかし残念なことに、/etc/service/myApp/runはすぐに呼び出されてサーバーを再起動します:(

私はシステム管理者ではないので、この側面のほとんどは私にとって新しいものです。必要なのは、自動再起動ではなく、ブート時に実行するスクリプトです。ご協力いただきありがとうございます。

編集:ここでrunitが使用されているという事実を含めるように質問を更新しました。 runitはプロセスを監視してサービスを維持しているようです。私の質問はまだ残っています。

3
Eric Olson

永遠に使用しないでください。

簡単です。既に確認したように、runitはすでにサービスマネージャーであり、プログラムを既に開始および再起動しているため、ここでは永遠に不要です。

すでに観察したように、runプログラムが実行する必要のあるルールはいくつかあります。 する必要はありません forkして、メインプログラムを終了します。 runitサービスマネージャは、ほとんどのdaemontoolsファミリサービスマネージャ(すべてこのように機能するソフトウェアファミリである)と同様に、runプログラムを実行するプロセスisdæmonを期待しています。親ではありません。分岐して終了する短い夜間飛行ではありません。しかし、実際のデーモン自体。

単純なrunプログラム

このようなrunプログラムの作成を楽にするさまざまなスクリプト言語があります。 Laurent Bercotのexecline は1です。 私のnoshプログラム は別です。 bin/wwwがデーモンの実際の実行可能プログラムであると仮定すると、nosh runスクリプトは次のようになります。

#!/ bin/nosh 
 fdmove -c 2 1 
 chdir /src
bin/www

Execlineスクリプトも同様に簡単です。しかし、シェルスクリプトはそれほど長くはありません。 runプログラムがis Shellスクリプトである場合、覚えておくべきことはShellプログラムをオーバーレイするを同じプロセスでデーモンプログラムと一緒にすることです。これを行うためのシェルコマンドはexecであるため、シェルスクリプトは次のようになります。

#!/ bin/sh -e 
 exec 2>&1 
 cd /src
exec bin/www

プログラムがスーパーユーザー権限を必要としない場合、viachpst プログラム(およびその-uオプション)を実行して、非-として起動することを強くお勧めします。特権ユーザー—最良の結果を得るために、このサービス専用のユーザー。

何年もの間、何人かの人々がrunプログラムのスイートを収集して公開してきましたが、ほとんどのrunプログラムは短くてシンプルです。 runitがあるので、Gerrit Papeのrunプログラムの独自のコレクションから始めることができます。

デーモンの開始と停止

サービスの開始と停止に関しては、ほとんどのdaemontoolsファミリのサービスマネージャーに、サービスの自動再起動を停止するように指示する必要があります。それらにはすべて、これを行うためのツールが付属しています。 clean-shutdownスクリプトで使用するだけです。

  • runitには sv プログラムがあります:sv down /etc/service/MyApp
  • s6には s6-svc プログラムがあります:s6-svc -d /etc/service/MyApp
  • perpには perpctl プログラムがあります:perpctl d /etc/service/MyApp
  • daemontoolsには svc プログラムがあります:svc -d /etc/service/MyApp
  • daemontools-encoreには svc プログラムがあります:svc -d /etc/service/MyApp
  • noshには service-control プログラム:service-control --down /etc/service/MyAppがあり、これもsvcとしてエイリアスされています:svc -d /etc/service/MyApp

私はそれがツールセットのファミリーだと言った。実際、これらのツールはすべて、ほとんど同じプロトコルを使用しています。

これは私に大きなポイントをもたらします。これらのツールセットはすべて排他的ではありません。 runitを使用しているからといって、execlineを使用することを止められません。または、s6のサービスマネージャーでnoshスクリプトを実行できます。

ロギング

あなたは永遠にログファイルを書き込もうとしました。繰り返しますが、永久に使用しないでください。これは、runitでログを記録する正しい方法ではありません。標準出力とエラーを直接ファイルにリダイレクトすると、ログのローテーション、サイズ制限、およびデーモンの操作を大幅に妨害することなく制御することができなくなります。

daemontools-familyサービスマネージャーall 1つの出力をログに記録しますmainサービスを通常のパイプを介して別の入力に接続しますlogサービス。このパイプは、サービスマネージャーによって設定されます。あなたは自分でそれをしません。

ログサービスはanother serviceです。標準入力から読み取り、厳密にサイズ制限され、自動的に循環される、オンデマンドでローテーション可能なログディレクトリ内のログファイルのセットに書き込む多くの利用可能なツールの1つを実行します。

これらのプログラムは multilogmultilogs6-logtinylogcyclog 、- svlogd 後者は、runitを備えたツールキットに含まれているものです。

実際、/etc/service/MyAppをセットアップした人は誰でも既にセットアップ済み/etc/service/MyApp/logのログサービスを持っていることに気付くでしょう。そうでない場合、ログサービススクリプトは非常に単純です。

#!/ bin/sh -e 
 exec chpst -uMyApp-log svlogd -t ./main

MyApp-logmkdir /etc/service/MyApp/log/mainchown MyApp-log /etc/service/MyApp/log/mainという名前のユーザーアカウントを作成するだけです。 (mainは、代わりにディレクトリを作成する他の場所へのシンボリックリンクになります。runitを使用してログを/etcの下に置く必要はありません。ログディレクトリを/var/log/svの下に置きます。)

mainサービスに何もせずに、ログの循環とサイズ制限を行います。 logサービスプロセスでは、サイクリングとサイズ制限が独立して行われます。

参考文献

4
JdeBP