nginxでクエリストリングのパラメータを判別して流量制御

最近nginxの流量制御フェチみたいになってますが、
ちょっと確認したいことがあったので試してみました。

確認したかったこと

クエリストリングを判定して流量制御できるか

項目・値どっちでもよかったのですが、
クエリストリングを元に流量制御したい要件があったので、確認してみました。

結果的に、項目の存在有無で流量制御する形となりました。
下記、設定と結果をレポートしたいと思います。

設定(抜粋)

 :
     limit_req_zone $arg_R1 zone=perserver4:50m rate=30r/s;
     limit_req_zone $arg_R2 zone=perserver5:50m rate=20r/s;
     limit_req_zone $arg_R3 zone=perserver6:50m rate=10r/s;
 :
        location /index.html {
           limit_req zone=perserver4  burst=2000;
           limit_req zone=perserver5  burst=2000;
           limit_req zone=perserver6  burst=2000;
           proxy_pass   http://192.168.0.110;
        }
 :

limit_req_zoneの制御設定対象に、$arg_XXと記載しています。
参考にしたドキュメントはこちら↓

Alphabetical index of variables

この例では、クエリストリングにR?が存在する場合、
設定した値のとおりに流量制御することとなります。

簡易検証結果

検証にはab(apache bench)を使いました。
サクッと検証するには超便利。

制御対象がR1の場合

これだけ見ても、わりかし期待通りに制御できていますね。
Request per secont がほぼ設定値の30[rps]に制限されています。

# ab -n 300 -c 50  http://192.168.0.111:81/index.html?R1=1
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.0.111 (be patient)
 :
 :
Server Software:        nginx/1.8.1
Server Hostname:        192.168.0.111
Server Port:            81

Document Path:          /index.html?R1=1
Document Length:        93 bytes

Concurrency Level:      50
Time taken for tests:   10.578 seconds
Complete requests:      300
Failed requests:        9
   (Connect: 0, Receive: 0, Length: 9, Exceptions: 0)
Non-2xx responses:      9
Total transferred:      135021 bytes
HTML transferred:       60705 bytes
Requests per second:    28.36 [#/sec] (mean)
Time per request:       1762.931 [ms] (mean)
Time per request:       35.259 [ms] (mean, across all concurrent requests)
Transfer rate:          12.47 [Kbytes/sec] received
 :
 :

制御対象がR2の場合

なかなかいい感じに制御されています。
Request per secont がほぼ設定値の20[rps]に制限されています。

# ab -n 300 -c 50  http://192.168.0.111:81/index.html?R2=1
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
 :
 :
Server Software:        nginx/1.8.1
Server Hostname:        192.168.0.111
Server Port:            81

Document Path:          /index.html?R2=1
Document Length:        93 bytes

Concurrency Level:      50
Time taken for tests:   14.954 seconds
Complete requests:      300
Failed requests:        4
   (Connect: 0, Receive: 0, Length: 4, Exceptions: 0)
Non-2xx responses:      4
Total transferred:      117176 bytes
HTML transferred:       42480 bytes
Requests per second:    20.06 [#/sec] (mean)
Time per request:       2492.313 [ms] (mean)
Time per request:       49.846 [ms] (mean, across all concurrent requests)
Transfer rate:          7.65 [Kbytes/sec] received
 :
 :

制御対象がR3の場合

ここまでくるともう想像通りですね。
Request per secont がほぼ設定値の10[rps]に制限されています。

# ab -n 300 -c 50  http://192.168.0.111:81/index.html?R3=1
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
 :
 :
Server Software:        nginx/1.8.1
Server Hostname:        192.168.0.111
Server Port:            81

Document Path:          /index.html?R3=1
Document Length:        93 bytes

Concurrency Level:      50
Time taken for tests:   29.925 seconds
Complete requests:      300
Failed requests:        5
   (Connect: 0, Receive: 0, Length: 5, Exceptions: 0)
Non-2xx responses:      5
Total transferred:      120745 bytes
HTML transferred:       46125 bytes
Requests per second:    10.02 [#/sec] (mean)
Time per request:       4987.575 [ms] (mean)
Time per request:       99.752 [ms] (mean, across all concurrent requests)
Transfer rate:          3.94 [Kbytes/sec] received
 :
 :

まとめ

ということで、クエリストリングベースで
nginxの流量制御をコントロールできることがわかりました。
なかなかそんな要件があることもないと思いますが、
何かの参考になればいいなと思います。