Ten Thousand
nginxとはずいぶん長い付き合いだった。いまは別の相手がいる。
商用版のNGINX Plusが出るはるか前、1.0を名乗る前から使っていた。当時はApacheが王者だった。httpd.confにVirtualHostを書き、mod_rewriteで転送ルールを積み上げ、preforkかworkerかでMPMを選ぶ。それが普通だった。nginxは得体の知れないロシア製のHTTPサーバーだった。
C10K問題が流行った時期がある。同時接続1万をどう捌くか。Apacheのpreforkモデルでは1接続に1プロセスを割り当てる。1万接続なら1万プロセスだ。1プロセスあたり数10MBとして、数100GBのメモリが要る。少なくとも当時は足りるわけがない。workerに切り替えてもスレッド数の上限がある。接続数だけプロセスを用意するモデルには限界がある。
nginxはイベント駆動だった。少数のワーカープロセスがepollで大量の接続をさばく。1接続1プロセスではなく、1プロセスが数千の接続を処理する。メモリ効率が桁違いに良い。設定もシンプルだった。Apacheのhttpd.confの煩雑さに慣れた身には、nginxのconfは拍子抜けするほど短かった。
ソシャゲ全盛の時代にnginxは一気に広まった。ガチャの結果を何万人が同時に叩く。イベント開始の瞬間にアクセスが集中する。Apacheでは捌けないトラフィックをnginxが吸収した。リバースプロキシとして前段に置くだけで、バックエンドの負荷が劇的に下がる。
振り分け、障害検知、キャッシュ。いまでいうL7のALBとCDNの役割を、あの頃はnginx一台が担っていた。置くだけで、だいたいの問題が片付いた。
いまではnginxは当たり前のインフラになった。CloudflareもAWSも裏でnginxか、その影響を受けたアーキテクチャが動いている。F5に買収されてからは商用路線が強くなり、forkのfreenginxも出てきた。ひとつの個人プロジェクトが、インターネットのトラフィックの相当な割合を支えている。
別の相手というのはOpenRestyだ。VictoriaMetricsにカスタムメトリクスを送りたくなった。エンドポイントごとのレイテンシ分布、特定のヘッダの有無、レスポンスサイズの偏り。nginxのconfでは書けない計測ロジックだった。stub_statusで接続数は見える。でもリクエストの中身に踏み込もうとすると、confの外に出るしかない。
OpenRestyならLuaでリクエストに触れる。log_by_luaでメトリクスを組み立て、VictoriaMetricsに送る。confに収まらなかったものが、数十行のLuaで実現する。nginxの設計思想はそのままに、プログラマブルな層がひとつ加わった感覚だった。
同時接続1万が問題だった時代がある。その命題は解決され、見届けられ、いまでは誰も口にしない。