最近unicornのことばかり考えていて夜も眠れない

タイトルは言い過ぎ。unicornのデザインまわりについて書いておく

unicornは普通のpreforkサーバ

unicornの哲学は「Keep It Simple, Stupid」な感じで、非常に良い。ひとつのプロセスで同時にさばけるリクエストの数はひとつに限定されていて、とっても見通しの良いデザインになっている。

でもまあこれは同時に(公式のドキュメントにも書いてあるけど)プロセスが外部サービスのAPIとかの遅いIOでブロックしてしまうときとかは、そのIOを待つ間はCPUは何もしてないのにプロセスを一つ占領してしまうみたいなことになって、もったいない、という話がある。

あるいは、コネクションはりっぱにしておいてじわじわストリーミングでなんか出力するみたいなアレ(TwitterのUserStreamsとかそういうアレ)の場合は、1コネクションがすごい長時間1worker占有しちゃうからこれもunicornみたいなアーキテクチャには合わない

解決策

ストリーミングするやつみたいな、クライアントがコネクション占有しちゃう系は素直に別のやつ使うのがいいと思う。RackアプリだったらRainbows!とかが選択肢としてあるみたいだけど、ストリーミングみたいなやつはそもそもRackアプリでやる必要あるのか?みたいなところから考えたほうがいいんじゃないかなーって個人的には思う。

バックエンドにブロックするIOがあるみたいな場合は、これは結構判断の難しいところで、素直にRainbows!とか使うっていうのでもいいんだけど、ブロックしちゃう時間がだいたい決まっているみたいな環境ならば、それを加味してworkerの数を決めるっていうのでも良い気がしている。理屈で言えば、いっさいブロックする部分がないようなRackアプリであれば、CPUのコアの数と同じだけのworkerにするのが一番効率がいいって話になるんだけど、ブロックする時間がだいたい決まってるなら、そのブロックしてる時間に他のプロセスがCPU使えるように、workerの数を調整してあげれば、ほとんどの場合はunicornで事足りるのではないかな、と思った。