首先献上一个本人在生产环境应用的一个较完整的Nginx主配置文件
#
user www www;
worker_processes auto;
#Specifies the value for maximum file descriptors that can be opened by this process.
pcre_jit on;
worker_rlimit_nofile 66600;
worker_shutdown_timeout 60s;
worker_cpu_affinity auto;
events {
use epoll;
worker_connections 66600;
}
http {
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
charset utf-8;
include mime.types;
default_type application/octet-stream;
# 老代码需要这个 clientRealIp 头,如果没有,网站会挂
map http_x_forwarded_forclientRealIp {
"" remote_addr;
~^(?P<firstAddr>[0-9\.]+),?.* firstAddr;
}
log_format main 'remote_addr - [remote_addr] -remote_user [time_local]'
' "request" statusbody_bytes_sent "http_referer" "http_user_agent" request_length'
'request_time [http_appid]upstream_addr "upstream_response_length"'
'upstream_response_time "upstream_status" "upstream_status" host [http_appkey] "request_id"' ;
log_format json '{"access_time": "time_iso8601", "remote_addr": "remote_addr", "x-forward-for": "http_x_forwarded_for", "method": "request_method", "request_url_path": "uri", "request_url": "request_uri", "status":status, "request_time": request_time, "body_bytes_sent": "body_bytes_sent", "request_length": "request_length", "upstream_host": "upstream_http_host", "upstream_response_length": "upstream_response_length", "upstream_response_time": "upstream_response_time", "upstream_status": "upstream_status", "http_referer": "http_referer", "remote_user": "remote_user", "http_user_agent": "http_user_agent", "request_id": "request_id", "appkey": "http_appkey", "upstream_addr": "upstream_addr"}';
sendfile on;
tcp_nopush on;
tcp_nodelay on;
proxy_next_upstream error http_502 timeout;
proxy_next_upstream_tries 2;
open_file_cache max=10240 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 1;
reset_timedout_connection on;
keepalive_timeout 45s;
keepalive_requests 2000;
client_header_timeout 15s;
client_body_timeout 15s;
proxy_connect_timeout 5s;
variables_hash_max_size 1024;
server_tokens off;
proxy_intercept_errors on;
fastcgi_intercept_errors on;
client_header_buffer_size 16k;
large_client_header_buffers 4 32k;
client_max_body_size 160m;
server_names_hash_max_size 512;
server_names_hash_bucket_size 128;
gzip on;
gzip_min_length 1k;
gzip_buffers 16 8k;
gzip_comp_level 6;
gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/json application/javascript;
gzip_vary on;
gzip_proxied any;
proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传递请求,而不缓冲到磁盘
client_body_buffer_size 256k;
proxy_buffer_size 64k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 64k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
proxy_buffering on;
limit_req_status 429;
limit_req_zonehttp_host zone=open_api_domain:50m rate=2800r/s;
limit_req_zone arg_appkey zone=open_api_appkey:50m rate=300r/s;
limit_req_zonebinary_remote_addr zone=zone_web_tmp:50m rate=5r/s;
limit_req_zone binary_remote_addr zone=zone_web:50m rate=30r/s;
limit_req_zonebinary_remote_addr zone=zone_web_yjtg:50m rate=30r/s;
limit_req_zone binary_remote_addr zone=zone_open_api:50m rate=300r/s;
mapsent_http_cdn_time expires {
default -1;
~^\d+ sent_http_cdn_time;
}
more_clear_headers Pragma;
set_real_ip_from 0.0.0.0/0;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
expiresexpires;
more_set_headers "Upstream-Name: proxy_host";
lua_package_path "{prefix}conf/conf.d/lrc4/?.lua;/opt/nginx/lua_modules/?.lua;/opt/nginx/lua/?.lua;/opt/nginx/lua_modules/?.lua;/opt/nginx/lua/?.lua;;";
lua_shared_dict domain_mem 10m;
lua_shared_dict open_url_mem_min 10m;
lua_shared_dict open_appkey_mem_day 10m;
lua_shared_dict my_limit_req_store 30m;
lua_shared_dict my_limit_req_api 30m;
lua_shared_dict cms_domain_mem 10m;
lua_shared_dict cms_domain_vipstatus_mem 20m;
lua_socket_log_errors off; # TCP发送失败的时候,会发送error日志到error.log,此过程会有性能开销,建议关闭,避免健康检查中多台机器down了,导致日志一直写入error.log。对于异常的情况请使用ngx.log来记录
lua_shared_dict healthcheck 2m; # 存放upstream servers的共享内存,upstream组越多,配置就越大。
proxy_redirect off ;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host host;
proxy_set_header X-Forwarded-Forproxy_add_x_forwarded_for;
proxy_set_header X-Request-Id request_id;
resolver 100.100.2.138 100.100.2.136 valid=30s;
# 静态化varnish缓存,轮训负载均衡主备
split_clients "request_uri" proxy_cache {
50% master_cache_servers;
* backup_cache_servers;
}
server {
listen 80;
server_name ~^\d+\.\d+\.\d+\.\d+;
setcms_uri '';
set $mysql_host_uri '';
return 444;
}
ssl_certificate conf.d/dtkcert/dataoke.com.pem;
ssl_certificate_key conf.d/dtkcert/dataoke.com.key;
include upstream.conf;
include conf.d/*.conf;
include testconfig/*.conf;
include blocksip.conf;
}
优势:
Nginx限流可以针对客户端的IP进行请求速率限制,既能够强行保证请求的实时处理速度,又能防止恶意攻击或突发流量导致系统被压垮,提升系统的健壮性。
在http模块中新增配置limit_req_zone全局配置
在http模块中新增配置limit_req_zone,如下:
http {
include mime.types;
default_type application/octet-stream;
server_tokens off;
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
- $binary_remote_addr表示根据remote_addr变量的值进行限制
- zone=mylimit:10m 表示一个大小为10M,名字为myRateLimit的内存区域,根据官方描述,1M的内存大约可以存储16000个IP地址,10M则可以存储约16万IP地址,可以根据实际情况调整
- rater=2r/s 表示限制每秒2个请求,Nginx 实际上以毫秒为粒度来跟踪请求信息,因此 2r/s 实际上是限制:每500毫秒处理一个请求。这意味着,自上一个请求处理完后,若后续500毫秒内又有请求到达,将拒绝处理该请求,默认返回503错误码,该错误码可以自定义。
在server中调用limit_req_zone
例:
server {
listen 8089;
server_name localhost;
root html/shigongbao;
autoindex on;
limit_req zone=mylimit burst=4 nodelay;
location / {
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
- zone=mylimit 表示调用http全局模块中定义的limit_req_zone zone名
- burst=4 表示缓冲区突然流量处理,在超过设定的处理速率后能额外处理的请求数。当 rate=2r/s 时,将1s拆成2份,即每500ms可处理1个请求。 当同时有10个请求到达时,rate=2 立刻转发了2个请求到后端服务器,burst=4 缓存或立刻转发了4个请求(是否立刻转发主要看nodelay参数),丢弃了4个请求
- Nodelay 针对的是burst参数,burst=4 nodelay 表示这4个请求立马处理,不能延迟,相当于特事特办。不过,即使这4个突发请求立马处理结束,后续来了请求也不会立马处理。burst=4 相当于缓存队列中占了4个坑,即使请求被处理了,这4个位置这只能按 500ms一个来释放。
执行ab压力测试
上述配置中rate=2r/s,burst=4,推理出第1秒可以一次性处理5个请求(因为rate=2 500毫秒内的第二个请求会被丢弃)
一次性发送5个请求测试结果,Failed requests: 0
[root@cs2 Yearning-go]# ab -n 5 -c 5 http://192.168.1.30:8089/
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 192.168.1.30 (be patient).....done
Server Software: nginx
Server Hostname: 192.168.1.30
Server Port: 8089
Document Path: /
Document Length: 394 bytes
Concurrency Level: 5
Time taken for tests: 0.002 seconds
Complete requests: 5
Failed requests: 0
Write errors: 0
Total transferred: 2545 bytes
HTML transferred: 1970 bytes
Requests per second: 2019.39 [#/sec] (mean)
Time per request: 2.476 [ms] (mean)
Time per request: 0.495 [ms] (mean, across all concurrent requests)
Transfer rate: 1003.78 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 1
Processing: 1 1 0.1 1 1
Waiting: 1 1 0.1 1 1
Total: 1 1 0.1 1 1
Percentage of the requests served within a certain time (ms)
50% 1
66% 1
75% 1
80% 1
90% 1
95% 1
98% 1
99% 1
100% 1 (longest request)
一次性发送6个请求测试结果,有一个请求被丢弃,Failed requests: 1
[root@cs2 Yearning-go]# ab -n 6 -c 6 http://192.168.1.30:8089/
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 192.168.1.30 (be patient).....done
Server Software: nginx
Server Hostname: 192.168.1.30
Server Port: 8089
Document Path: /
Document Length: 394 bytes
Concurrency Level: 6
Time taken for tests: 0.018 seconds
Complete requests: 6
Failed requests: 1
(Connect: 0, Receive: 0, Length: 1, Exceptions: 0)
Write errors: 0
Non-2xx responses: 1
Total transferred: 3226 bytes
HTML transferred: 2464 bytes
Requests per second: 328.62 [#/sec] (mean)
Time per request: 18.258 [ms] (mean)
Time per request: 3.043 [ms] (mean, across all concurrent requests)
Transfer rate: 172.55 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 4 5 0.3 5 5
Processing: 5 5 0.0 5 5
Waiting: 5 5 0.1 5 5
Total: 9 9 0.3 10 10
ERROR: The median and mean for the total time are more than twice the standard
deviation apart. These results are NOT reliable.
Percentage of the requests served within a certain time (ms)
50% 10
66% 10
75% 10
80% 10
90% 10
95% 10
98% 10
99% 10
100% 10 (longest request)
Nginx error日志记录被丢弃的包如下:
2020/07/29 16:00:08 [error] 4471#0: *895 limiting requests
文章评论