Nginxで、リクエストを複製するmirrorモジュールが標準搭載された

[20170809追記] nginx-1.13.4に ngx_http_mirror_module は含まれました


Nginxで、リクエストを複製するmirrorモジュールがコミットされ、何もせずとも使用できるようになりそうです(現状最新コミットをビルドする必要あり)。

例えば本番環境のproxyからリクエストを複製して開発環境に流すような事も出来ます。もちろん複製処理は本来のリクエスト処理をブロックしません。

例えば以下のように、mirrorに来たリクエストを複製してバックエンドサーバに投げるようにしてみます
f:id:ASnoKaze:20170724032715p:plain

conf

    server {
        listen       80 ;
        server_name  localhost;

        mirror_request_body on;
        log_subrequest on;

        location /mirror {
            mirror /proxy; #/proxy宛にリクエストを複製する
        }
        location /proxy {
            proxy_pass http://127.0.0.1/proxyed/;#任意のサーバにproxyする
        }
    }
  • mirror ディレクティブでリクエストを複製し、自身の任意のPATHにリクエストを送ります。今回は別のサーバに送るために一旦 /proxy宛に複製します($request_uriは変更されません)。proxy_passではいつも通り任意のサーバにリクエストを送ります。
  • log_subrequestを有効にすると複製したリクエスト自体もaccess.logに記録されるようになります。
  • mirror_request_body はおそらくPOSTのデータと言ったリクエストボディも合わせて複製されるようになるものだと思います。

もちろん2つ以上複製することもできます

動作確認

上記 .conf では、access.logに3つのリクエストが記録される。
本来のリクエスト、log_subrequest onによって記録される複製されたリクエスト、自身にproxyされたのを受け取ったリクエス

vagrant@vagrant:~/nginx-mirror$ curl localhost/mirror
mirror

vagrant@vagrant:~/nginx-mirror$ tail -f /usr/local/nginx/logs/access.log
127.0.0.1 - - [23/Jul/2017:18:08:14 +0000] "GET /proxyed/ HTTP/1.0" 200 0 "-" "curl/7.47.0"
127.0.0.1 - - [23/Jul/2017:18:08:14 +0000] "GET /mirror HTTP/1.1" 200 256 "-" "curl/7.47.0"
127.0.0.1 - - [23/Jul/2017:18:08:14 +0000] "GET /mirror HTTP/1.1" 200 7 "-" "curl/7.47.0"

(本来のリクエストのログは複製処理が終わったあとに出るが、本来のリクエストへのレスポンス処理はブロックされていないように見えました)

追記2018/04/11
tagomoris先生の検証記事が非常に分かりやすくて素晴らしいです
tagomoris.hatenablog.com



便利!!