1. limit_req_zone配置限流
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;upstream myweb {server 10.0.105.196:80 weight=1 max_fails=1 fail_timeout=1;}server {listen 80;server_name localhost;location /login {limit_req zone=mylimit;proxy_pass http://myweb;proxy_set_header Host $host:$server_port;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}}
limit_req_zone指令通常在HTTP块中定义,使其可在多个上下文中使用,它需要以下三个参数:
-
Key - 定义应用限制的请求特性。示例中的 Nginx 变量
$binary_remote_addr
,保存客户端IP地址的二进制形式。这意味着,我们可以将每个不同的IP地址限制到,通过第三个参数设置的请求速率。(使用该变量是因为比字符串形式的客户端IP地址$remote_addr
,占用更少的空间) -
Zone - 定义用于存储每个IP地址状态以及被限制请求URL访问频率的共享内存区域。保存在内存共享区域的信息,意味着可以在Nginx的worker进程之间共享。定义分为两个部分:通过
zone=keyword
标识区域的名字,以及冒号后面跟区域大小。16000个IP地址的状态信息,大约需要1MB,所以示例中区域可以存储160000个IP地址。 -
Rate - 定义最大请求速率。在示例中,速率不能超过每秒10个请求。Nginx实际上以毫秒的粒度来跟踪请求,所以速率限制相当于每100毫秒1个请求。因为不允许”突发情况”(见下一章节),这意味着在前一个请求100毫秒内到达的请求将被拒绝。
localtion中limit_req调用限流变量和使用参数:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;upstream myweb {server 10.0.105.196:80 weight=1 max_fails=1 fail_timeout=1;}server {listen 80;server_name localhost;location /login {limit_req zone=mylimit burst=20;proxy_pass http://myweb;proxy_set_header Host $host:$server_port;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}}
burst
参数定义了超出zone指定速率的情况下(示例中的mylimit
区域,速率限制在每秒10个请求,或每100毫秒一个请求),客户端还能发起多少请求。上一个请求100毫秒内到达的请求将会被放入队列,我们将队列大小设置为20。 如果你设置了每秒只允许 10 个请求,并且 burst 为 5,那么在短时间内可能会有 15 个请求被接收,但只有 10 个会立即被处理,剩下的 5 个会在“缓冲区”中等待。
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;upstream myweb {server 10.0.105.196:80 weight=1 max_fails=1 fail_timeout=1;}server {listen 80;server_name localhost;location /login {limit_req zone=mylimit burst=20 nodelay;proxy_pass http://myweb;proxy_set_header Host $host:$server_port;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}}
使用nodelay
参数,Nginx仍将根据burst
参数分配队列中的位置,并应用已配置的速率限制,而不是清理队列中等待转发的请求。相反地,当一个请求到达“太早”时,只要在队列中能分配位置,Nginx将立即转发这个请求。将队列中的该位置标记为”taken”(占据),并且不会被释放以供另一个请求使用,直到一段时间后才会被释放(在这个示例中是,100毫秒后)。
2. 白名单进行限流
default默认为1,设置上面两个网段可通过为0,经过map映射处理为""和$binary_remote_addr
经过这个调用 limit_req_zone $limit_key zone=req_zone:10m rate=5r/s;
如果为上面网段内的则不会限流,不是的话会进行限流
3. 通过location进行拒绝和允许请求
server {listen 80;server_name localhost;location /foo.html {root /home/www/html;deny 192.168.241.0/24;allow all}
}
上面为拒绝192.168.241.0/24网段内的 允许其它所有的ip进行访问
4. 一些常用的内置预定义变量
变量名 | 定义 |
---|---|
$arg_PARAMETER | GET请求中变量名PARAMETER参数的值。 |
$args | 这个变量等于GET请求中的参数。例如,foo=123&bar=blahblah;这个变量只可以被修改 |
$binary_remote_addr | 二进制码形式的客户端地址。 |
$body_bytes_sent | 传送页面的字节数 |
$content_length | 请求头中的Content-length字段。 |
$content_type | 请求头中的Content-Type字段。 |
$cookie_COOKIE | cookie COOKIE的值。 |
$document_root | 当前请求在root指令中指定的值。 |
$document_uri | 与$uri相同。 |
$host | 请求中的主机头(Host)字段,如果请求中的主机头不可用或者空,则为处理请求的server名称(处理请求的server的server_name指令的值)。值为小写,不包含端口。 |
$hostname | 机器名使用 gethostname系统调用的值 |
$http_HEADER | HTTP请求头中的内容,HEADER为HTTP请求中的内容转为小写,-变为_(破折号变为下划线),例如:$http_user_agent(Uaer-Agent的值); |
$sent_http_HEADER | HTTP响应头中的内容,HEADER为HTTP响应中的内容转为小写,-变为_(破折号变为下划线),例如: $sent_http_cache_control, $sent_http_content_type…; |
$is_args | 如果$args设置,值为"?",否则为""。 |
$limit_rate | 这个变量可以限制连接速率。 |
$nginx_version | 当前运行的nginx版本号。 |
$query_string | 与$args相同。 |
$remote_addr | 客户端的IP地址。 |
$remote_port | 客户端的端口。 |
$remote_user | 已经经过Auth Basic Module验证的用户名。 |
$request_filename | 当前连接请求的文件路径,由root或alias指令与URI请求生成。 |
$request_body | 这个变量(0.7.58+)包含请求的主要信息。在使用proxy_pass或fastcgi_pass指令的location中比较有意义。 |
$request_body_file | 客户端请求主体信息的临时文件名。 |
$request_completion | 如果请求成功,设为"OK";如果请求未完成或者不是一系列请求中最后一部分则设为空。 |
$request_method | 这个变量是客户端请求的动作,通常为GET或POST。包括0.8.20及之前的版本中,这个变量总为main request中的动作,如果当前请求是一个子请求,并不使用这个当前请求的动作。 |
$request_uri | 这个变量等于包含一些客户端请求参数的原始URI,它无法修改,请查看$uri更改或重写URI。 |
$scheme | 所用的协议,比如http或者是https,比如rewrite ^(.+)$ $scheme://example.com$1 redirect; |
$server_addr | 服务器地址,在完成一次系统调用后可以确定这个值,如果要绕开系统调用,则必须在listen中指定地址并且使用bind参数。 |
$server_name | 服务器名称。 |
$server_port | 请求到达服务器的端口号。 |
$server_protocol | 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。 |
$uri | 请求中的当前URI(不带请求参数,参数位于args),不同于浏览器传递的args),不同于浏览器传递的args),不同于浏览器传递的request_uri的值,它可以通过内部重定向,或者使用index指令进行修改。不包括协议和主机名,例如/foo/bar.html |