コンテンツにスキップ

ライフタイム

nginxは、設定を読む間に、http {}ブロックに1つ、stream {}ブロックに1つのmrb_stateを作ります。nginxがワーカープロセスをforkすると、各ワーカーはその状態の自分のコピーを持ちます。ワーカーは、自分のすべてのリクエストのRubyのコードを、そのコピーで実行します。状態はリクエストごとには作らないので、あるリクエストが状態の中に残したものを、同じワーカーの次のリクエストが見ます。

http {}ブロックのmrb_stateを、nginxが設定を読むときからワーカーが終わるまで示します。ngx_mrubyのソースの次の行から描きました。2026-10-19のコミット0c72e3970の行です。
  • src/http/ngx_http_mruby_module.cの575行から598行、600行から632行、727行から730行、1136行から1142行、1282行から1300行、1421行から1450行

ワーカーがリクエストをまたいで保つもの

Section titled “ワーカーがリクエストをまたいで保つもの”

nginxは、設定を読む間に、http {}ブロックに1つのmrb_stateを作り、stream {}ブロックにも1つ作ります。nginxは、ワーカーを起動する前に、masterプロセスで、その状態を使って初期化のコードとserverの設定のコードを実行します。そのうち初期化のコードはmruby_initとmruby_stream_initで、serverの設定のコードはmruby_server_context_handler_codeです。nginxがワーカープロセスをforkすると、各ワーカーは自分のコピーを持ちます。ワーカーは、そのブロックのほかのmrubyのコードを、すべてそのコピーで実行します。init_workerとexit_workerのコードと、すべてのserverとlocationのハンドラとフィルタを、すべてのクライアントについて実行します。リロードや再起動では、新しいワーカーが新しい状態とともに起動します。

グローバル変数、定数、mainのインスタンス変数、defで定義したメソッド、定数を含むクラスとモジュール、Userdataが持つ値は、リクエストをまたいでワーカーに残ります。mainは、ハンドラのコードのselfのことです。Userdataは、値を1つのグローバル変数に入れて保持します。あるリクエストが残したものは、同じワーカーが後に処理するすべてのリクエストから見えます。変更の後にコードが例外を起こした場合も同じです。各ワーカーは自分のコピーを持つので、あるワーカーから、ほかのワーカーの値は見えません。ngx_mrubyは、実行が終わるたびに例外のmrb->excを消します。また、cacheの無いスクリプトのファイルを、次の実行のときに読み直してコンパイルします。インラインのコードとキャッシュしたスクリプトは、起動時にコンパイルしたバイトコードのままです。ガベージコレクタは、参照されなくなったオブジェクトを解放します。ローカル変数は残りません。ハンドラのコードは、実行のたびにローカル変数の無い状態から始まります。

1つのリクエストのデータを、グローバル変数、定数、mainのインスタンス変数、Userdataに置かないでください。そのワーカーの次のリクエストが、どのクライアントからのものでも、そのデータを見ます。ローカル変数を使い、リクエストはNginx::Request、Nginx::Var、Nginx::Headers_in、Nginx::Headers_outで読み書きしてください。stream {}ではコードがセッションごとに動くので、Nginx::Stream::Connectionで読み書きしてください。同じリクエストの後のハンドラへデータを渡すには、set $name "";でnginxの変数を宣言し、Nginx::Varで読み書きします。または、Userdataの値を、読む前にすべてのリクエストで設定します。locationのsetはmruby_rewrite_handlerの後に動き、変数を空に戻します。そのため、rewriteハンドラが書く変数は、server {}ブロックのsetで宣言してください。グローバル変数と定数には、initやinit_workerのコードが用意する設定のような、ワーカーのすべてのリクエストで共有するものだけを置いてください。グローバル変数は、Nginx.remove_global_variableで消せます。

stream {}ブロックのRubyのコードも、自分のmrb_stateで同じように動きます。そこで動くのは、mruby_stream_init、mruby_stream_init_worker、各セッションのコードと、mruby_stream_exit_workerです。