人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

CentOS7におけるシェルスクリプトをサービス化する際の質問です。終了指示するまでは何年も永久にサービスを稼働し続けたいのですが、記述に気を付けるべき点を教えてください。

一定時間毎に起動させたい外部と通信するPHPがあります。
cronから呼び出すようにしたところ動作間隔がまちまちでイマイチでした。
そこで、無限ループするシェルスクリプトを記述してPHPを呼び出す際、開始時間と終了時間の差からsleepを入れるようにしたところ、想定通りの間隔で動作するようになりました。
当然ログアウト後も常時動作させたいので /etc/systemd/system に記述したところ(追記に記載します)…当時はサービスとして正常に起動していましたが、数週間後の昨日PHP部分?にて勝手に無限ループが停止しました。

PHPの実行時に何かあったのかもしれませんが…強制終了しようがそれはログに記録しておいて(としていたのに今回はログを調べていても原因が見つからないので困っていますが、それは一旦置きます)、構わず無かったかのように自動でそのまま無限ループを続けさせたいので、何卒よろしくお願い致します。

●質問者: くじぇ
●カテゴリ:ウェブ制作
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

質問者から

> 当然ログアウト後も常時動作させたいので /etc/systemd/system に記述したところ(追記に記載します)

/etc/systemd/system に call__hogehoge.service として以下のように記述しています。

[Unit]
Description = call__hogehoge daemon

[Service]
ExecStart = /var/www/cron/hogehoge.sh
ExecStopPost = /var/www/cron/hogehoge.sh
Restart = always
Type = simple

[Install]
WantedBy = multi-user.target

※勿論hogehogeの部分は仮名です。

以上よろしくお願い致します。


1 ● a-kuma3
●50ポイント

ずーっと動いているはずのプロセスが止まる原因として、ふたつほど思いつきます。

trap でシグナルを捕捉してください。
$? を残しておけば、どのシグナルを受け取ったか分かります。
何らかの理由で外部から受け取ってるかもしれませんし、スクリプト中の echo は PIPE を通してファイルなどに書かれるでしょうから SIGPIPE を受け取る可能性はあります。

プロセスの制限の方は、ulimit で設定するあれです。
/etc/systemd/system/ の [Service] のところで定義できます。

使えるのは、こちらの Limit で始まるやつ。
http://www.ict.griffith.edu.au/teaching/3420ICT/cgi-bin/man.cgi?systemd.directives+7

CPU とか FSIZE とか、上限に達していても不思議ではありません。



後は、考え方を変えてループしない作りにしてみるとか。
sleep した後に、自分自身を nohup でバックグラウンドで起動する。

#! /bin/sh

...
sleep $diference_time

nohup hogehoge.sh &

# もうひとつ呼び出しておいて、自分は終了する

echo は、なにがしかのファイルにめがけて吐きましょう。


くじぇさんのコメント
a-kuma3さんありがとうございます。 シェルスクリプトのサービス割り当て自体今回が初めてなので、ご説明いただいた内容についてまだ意味が理解できていないところがあるのですが、租借させていただきます!

くじぇさんのコメント
a-kuma3さんありがとうございます。 通信プロセスにおけるタイムアウト処理が怪しいことがわかりましたので、その辺を強化して様子を見ることになりました。

2 ● uunfo
●50ポイント ベストアンサー

ExecStopPost = /var/www/cron/hogehoge.sh

これはいらないと思います。

Restart = always

これが入ってるなら異常終了しても再起動するはずなんですが…。
ログに何か出てませんか?

あと無限ループするシェルスクリプトですが、これで一応希望通りの動作はするでしょうけど書き方がすごく変です(echoのタイミングとかphp-cgiとかwaitとか)。


くじぇさんのコメント
uunfoさんありがとうございます。 本題から外れるので一部元のソースから削っているのですが、削り切れなかった部分がありましてすみません。 お手数をおかけしています。 php-cgiは、(消しています)デバッグ時と本番時で別の値が入るようになっており、PHPへオプションにて別の値を渡すために使用しました。 waitについては、これと連動するシェルスクリプトのためにディスクへフラグとしてのファイルを書き込む処理があるのですが(消しています)、処理のタイミングを合わせる為に使用していました。 (コメント欄編集したいんですがどうすればよいのでしょう?一旦消して再度上げなおすしかないのでしょうか?)

uunfoさんのコメント
コメントの編集はできませんね。削除して上げなおすしかありません。 php-cgiだとHTTPヘッダーが出力されるので、php-cliを使うべきだと思います。 waitの理由はわかりました。 「無限ループが停止しました」というのは実際にこのシェルスクリプトのプロセスがなくなっていたということでしょうか? そうでないなら、他と処理のタイミングを合わせるところでデッドロックが発生していた可能性があるように思います。またはPHPの処理が終わらなかったとか。

くじぇさんのコメント
uuinfoさんありがとうございます。 ログの記録からPHP内に実装していた通信プロセスにおけるタイムアウト処理が怪しいことがわかりましたので、その辺を強化して様子を見ることになりました。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ