IISのWorkerProcessの挙動について

前提

Webサーバー1台構成だが、接続のたびに挙動が異なることがある。ブラウザごとに「挙動※1」が異なることがある。WorkerProcessの「設定」についてを言及した情報はあふれているが、挙動について調査してみたい。
※1 表示ではない。表示がおかしい場合は、十中八九ブラウザにキャッシュが残っているのが原因。


■そもそもWorkerProcessってなに?

IIS6.0限定のお話になるが、Http通信のリクエストの受付をHttpリスナーが行い、WorkerProcessに仕事が割り振られる。リクエストの割り振り先がWorkerProcessだ。Httpリスナーに対して、WorkerProcessは1対多の関係(※2)にあると考えていいだろう。ただし、Apacheのように自動的にfork(※3)してくれたりはしない。

リクエストの処理を行う部分なので、今の時代CPUの性能面、メモリの性能面を考えると、シングルで動かす意味は薄いので多いに越したことはない。サーバーにアクセスが集中したときに、内部エラー(500)とかセッションタイムアウトが起きているのであれば、WorkerProcessの調整を検討するというのも一つの方法だ。

リアルと一緒で、仕事を割り振る先が増えれば、当然レスポンスも向上する。

※2 IISの設定がデフォルトの状態のときは、WorkerProcessは一つなので、1対1になっているので注意。
※3 preforkのケースでのお話。forkとはIISのWorkerProcessに当たる部分。Apacheはリクエスト単位で処理を行うプロセスを自動的に増やしてくれる。それなりに負荷があるが早い。IISが遅い(と言われている)のは、この辺の足回りの設計の違いにもあるんだと思う。

■本題に入る前に、そもそもHttp通信ってどんな通信?

最近たびたび感じるのだが、若いエンジニアだけででなく、主力となる年齢層のエンジニアも「結果」は理解しているものの、仕組みの部分は理解しきれていないのでは?と懐疑的になることがある。Webの仕事が中心ということもあるのか、なかでも、Http通信に関してとくにちょっとした違和感を会話の端々に感じる。

ちょっと余談になるが、aspxを作成したときに、Page_Loadというイベントがデフォルトで呼ばれる。まぁ、文字通りページのデザインやパーツがメモリにロードされたときに発生するイベントだ(リクエストは事前のInitで受付済み)。この後にRenderイベントが続くのだが、その処理工程でクライアントに「何を」渡しているのか?

あえて述べることもないと思うが、htmlと呼ばれる文書構造のテキストが各々のPCに送信されている。その文書構造が、下記に当たる部分。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

今どきのWebページは下記になっているはず。

<!DOCTYPE html>

リクエストを受け取って、指定の書式にのっとったhtmlタグを生成、クライアントに返すというのがHttp通信の一連の流れだ。画面の描画は、ブラウザの機能であってサーバーの機能ではない。

■WorkerProcessの挙動について
さて、ここまでの流れで考えると、Htmlタグを生成してくれる「人」がWorkerProcessに当たる、というのは理解いただけると思う。

「人」と定義したのには理由がある。実のところ、WorkerProcessは共通認識を持ってはいるものの、それぞれ違った個性を持つ。これが、WorkerProcessごとの挙動の違いになって表れる。例を挙げると、10分ごとにサイトのグローバルナビの色が徐々に変化していくサイトがあったとする。10分のカウントを行うのはサーバーサイドだ。この条件下では、グローバルナビの色は必ずしも「10分後」に色が変化することはほぼない。

・プロセス1 9:30経過
・プロセス2 8:00経過
・プロセス3 2:30経過
・プロセス4 0:00 更新状態

といったように、カウントの起点がWorkerProcessごとに異なるからだ。

Httpリスナーのほうで保障しているセッション情報やリクエスト情報は共通だが、WorkerProcessが「処理する情報」はそれぞれ違うのだ。しかも、高級なロードバランサのように接続サーバーを極力単一化しようとする動きはないようなので、接続ごとに異なるWorkerProcessで処理される。おそらく、単純振り分けされているのだろうと思う。

このような処理を実装したいのであれば、共通個所のセッションに何らかのキー情報を持つか、クライアントサイドでjavascriptで組み込むのがいいだろう。

まとめ

WorkerProcessは、プロセスごとに固有の情報をメモリに保持している。なので、挙動の違いを許容できない機能の場合は、事前に「どのように処理を行うのがよいのか」を設計しておく必要がある。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です