limit_req の使い方 (基本)
http {
...
limit_req_zone $binary_remote_addr zone=zone1:1m rate=5r/s;
server {
...
location = /some/application/path {
limit_req zone=zone1 burst=5;
...
}
}
}
上記の例では、/some/application/path へのリクエストについて、毎秒5リクエストの割合に制限している。
limit_req_zone
は http ブロックにしか記述できない点に注意が必要。
limit_req の適用を特定の条件に絞る
以下は間違い
http {
...
limit_req_zone $binary_remote_addr zone=zone1:1m rate=5r/s;
server {
...
location = /some/application/path {
if ($http_user_agent ~* "android.*mobile") {
limit_req zone=zone1 burst=5;
}
...
}
}
}
ngx_http_limit_req_module#limit_req に書かれているとおり、limit_req
ディレクティブは if ブロックに書けない。
正しい例
http {
...
limit_req_zone $limit_req_key zone=zone1:1m rate=5r/s;
server {
...
location = /some/application/path {
limit_req zone=zone1 burst=5;
if ($http_user_agent ~* "android.*mobile") {
set $limit_req_key $binary_remote_addr;
}
...
}
}
}
http ブロックに記述した limit_req_zone
の第一引数 (key) を、$binary_remote_addr
から $limit_req_key
に変更している。そして、$limit_req_key
を if ブロックの中で set している。ここがミソで、limit_req_zone
で指定する key が空 (値なし) の場合は、制限がかからないのである。ngx_http_limit_req_module#limit_req_zone に書かれている。
The key can contain text, variables, and their combination. Requests with an empty key value are not accounted.
Requests with an empty key value are not accounted. とは英語のネイティブでない私には意味がわかりにくかったのだが、要するに「...の場合は制限が適用されない」と解釈した。
逆に特定の条件で制限を適用しない場合は、以下のようにすれば良いだろう。
location = /some/application/path {
limit_req zone=zone1 burst=5;
set $limit_req_key $binary_remote_addr;
if ($http_user_agent ~* "android.*mobile") {
set $limit_req_key "";
}
なお、本項では limit_req で説明したが、limit_conn でも全く同様のはずである。