Archive for 2009/5/21
久々にphpでサーバもどきのプログラムを作成することになった。
ここから書くことは別にphpに限ったことではないのだが、phpのプログラマたちはよく知らないことがあるので書いてみた。
ここでサーバもどきと言っているのは、WEBサーバのようにデーモンとして起動し負荷なども十二分に考えなくてはならないものでもないが、かといって、バッチよりもリアルタイムの処理をしたい場合という場合のプログラムだ。
たとえば、あるトランザクション処理があるが、それを来た順に処理をしていきたいという場合。でも、サーバが忙しければ時間がかかってもいいし、でも、なるはやで処理してなんて場合。
たとえば、レポートシステムなんかはそれに値するだろう。はじめは、WEBでリクエストがあった時にその場で記録・計算をするのだが、リクエストが多くなるとそうもいかない。
また、サーバの役割の分担なんかも考えるとレポートシステムだけ別サーバでひたすら計算、レポート作成をやらせるなんて感じかな。
このときに、よく見かけるのが、CSVファイルを作成してそれをレポートサーバに送り、cronで計算なんて感じだ。
これだと、レポートに時間がかかりすぎた場合などに重複して処理がされないようにとか・・・・
CSVファイルをどうやって転送するか( SCP,FTP ? )。でも一番多いのがNFSなのかな。などなど、いろいろと考えることが出てくる。
こんな時に使えるunixな環境は・・・
名前付きpipe
と
syslog
だ。
phpでは名前付きpipeはposix_mkfifoで作れる。
別に最初に作ってしまえば、プログラムで作るほどでもないが、読み書きはいつもどおりfopenだ。
これが結構使える。
まず、作成した名前付きパイプ(プログラマからは単なるファイル)に対してプログラムで、書き込むほうと読み込むほうを作成する。
そうすれば、それらのプログラム間の通信ができる。
しかも、だいたい読み手は一つにし、書き手を複数にしても排他ができているのでさらに便利だ。
キュー型のトランザクションを簡易的にすぐに作れる。
これで、cronで処理をしなくてもずーーと処理を回していればいい。
書き込みがなければ、まっているだけだ・・・
さて、書き込みのほうだが、WEBのレポートをする情報をphpでsyslogに書けばいい。
syslogでレポートサーバに飛ばせば、scpも、ftpもいらない。
さて、先ほどの名前付きパイプとsyslogを挙げたのは、この2つを連携することにある。
syslogではsyslog-ngという別のsyslogデーモンがあり、これは出力を名前付きpipeに書き込めるのだ。
これで、あるサーバが出力したトランザクション処理をべつのサーバが受け取って処理をしていくというサービスが簡単に作れる。
しかも、ほぼリアルタイムだ。
この「ほぼ」というのがシステム運用をするようになると非常に助かる。
だって、忙しい時はサーバの負荷を高めず、遅れるということができるのだから。
さらに、入力ファイル名が1つでいいということは非常に重要だ。
これのおかげでよりプログラムが単純になるのだ。
余談だが、ある会社のシステムを見たら、なぜかsystemのCPU負荷が90%を超えるようなプログラムを作っていたが、
こんなプログラムは売らないでほしい。しかも、原因を言っても理解できないと来ている。
(言語はJavaを使っていたのだが、Javaのせいじゃないかといってきかない。だから、Javaでおかしなことをしているからだろーー!。
動かぬ証拠を突きつけても、その証拠の意味が理解できない会社があるので要注意だ。こういうエンジニアがいるせいでJavaエンジニアは信用できないという人がでてきてしまうのだ・・・)
さて、 次はシグナルだ。
プログラムを途中で中断したい場合があるが、安全に中断したい。
メール配信などを作っていればよりそんな必要性がある。
これもプログラムしか知らない人がつくったものをみると、中断ファイルなどを作って、それを見る仕様になってしまっている。
Apacheだって他のプログラムだってシグナルで処理に対して安全に停止、再起動などをするのはシステム運用者から見れば普通だ。
だったら、その普通に合わせるのがいいプログラムってものだろう。
phpのシグナルの処理のしかたはマニュアルを見ればわかると思う。
while文でループしているところに、シグナルでループを止めるようにすれば安全に止まるように作れる。
これであれば、中断ファイルが消せなかったらとか、排他処理とか・・・も考えなくていいだろう。
さらに、シグナルを使うのであれば、そのプログラムが動いたときのプロセスIDファイルを作ったほうがいい。
だいたいのサービスはこのプロセスIDファイルがあるのに、プロセスがない状態ならばおかしな状態で落ちたよ!って起動時に出力され、
問題なければ、このファイルを消して起動して!ってメッセージが出てくる。
こんな感じで環境全体を考えよりサービスレベルにあったプログラムを作っていきましょう。


