限流配置
http block添加,limit_req_zone $server_name(也可以改成$binary_remote_addr,针对单一id限制) zone=xxx:100m rate=10000r/s;
server block添加,limit_req zone=xxx burst=2000 nodelay;
上述内容,表示针对同一个server block(如443 端口所有域名),每秒仅可通过1w个请求,超出部分有2000可以也可在1s内接受处理(因为总量=burst+nodelay)
-
不同算法:
a. nodelay时是令牌桶(token bucket)算法,nginx下精确最小时间刻度为1ms,即1ms生成2个令牌,即最多瞬间(1ms)可处理12个并发qps,1.2w请求用时1s,超出1.2w请求报503;b. 没有nodelay时为漏桶算法,1s若来了1.2w请求,则1s内处理1w的请求,剩下2000不会报503错误,会在下一秒内处理掉,速度还是和1w r/s一样,所以1.2w请求用时1.2s,但是该算法会让整体越来越慢,堆积越慢,建议使用nodelay
优化性能配置:
-
全局(最外侧block):
a. worker_processes: 数目即为工作进程数,若支持auto则最佳,不然手动根据cpu数目(lscpu)来调整1:1;b. worker_rlimit_nofile: 每个套接字都会打开一个fd, 该大小应大于下方B.c中计算的nginx总的最大连接数。
-
event block:
a. accept_mutex: 每个可用worker逐个接受新连接,避免惊群现象,默认是on;b. accept_mutex_delay: 逐个接受新连接间的等待间隔,默认500ms;
c. worker_connections: 单个worker最大连接数,默认512(nginx总的最大连接数 = worker_connections * worker_processes);
d. multi_accept: 立刻接受所有连接放到监听队列中,注意!accept_mutex是让多个worker进程逐个接受连接防止惊群,而multi_accept是让单个woker加速效率。
-
http block:
a. sendfile: 类似kafka的零拷贝的优化,默认是off不开启的- 原本:是把数据从disk读到read buffer(都在kernel),再从read buff到application(用户态),再从application复制到socket buffer(回到kernel),再到nic buffer传出去;
- 现在:通过dma(direct memory access)将数据从disk到read buffer,然后从read buffer直接传输给nic buffer(网卡设备)
b. tcp_nopush: 结合sendfile on才可使用,让数据到read buffer满了,再发送到nic buffer;
c. tcp_nodelay: 禁用nagle算法(nagle算法只允许网络上有一个小包,在该包确认收到之前,会将小包累积起来一并发送,若达到mss或有FIN则提前发送,否则最多会等待200ms<默认值>也会发送),禁用后所有tcp包都瞬间发出去,默认是on(默认会禁用nagle);
d. tcp_cork: 替代nagle算法,可配合tcp_nodelay一起使用,没有200ms的限制,只发送mss大小的包和fin的包,除了可在http block配置,也于server & location;e. 网络吞吐buffer优化:除了可在http block配置,也可在server & location
- client_body_buffer_size: 设置request的body的缓存区大小,request先进入缓冲区,64位默认16k。若body大于buffer_size,则部分写入临时文件;
- client_body_timeout: 在连续读取两次客户端request间的超时时长,如果客户端在这段时长内没传输任何数据,返回408;
- client_max_body_size: 请求最大size,超出直接返回413(上传大文件时必须修改),若header超出size返回408;
- client_body_in_file_only: on,请求存储在文件中;clean,请求写入文件,处理请求后文件被清除;off,则禁用文件写入,默认为off
f. 缓存静态内容优化:高流量网站仍需对此优化,缓存fd和其他nginx相关元数据,但不存储请求文件的内容
- open_file_cache: 具体可设置为open_file_cache max=1000 inactive=60s 为1000个元素(lru策略,移除最近最少使用)设定缓存,60s过期;
- open_file_cache_valid: 验证缓存是否仍然有效
g. proxy优化:
- proxy_connect_timeout: 和后端建立连接超时,默认60s(下方两个也是默认60s)
- proxy_read_timeout: read后端的request超时(下载大文件超时,理论不会出现,因为内网速度很快);
- proxy_send_timeout: send给后端超时,(上传大文件场景居多,理论也不会出现);
- 特殊场景注意:大文件上传下载时都需要注意,nginx可能并不直连client,前面还有一层SLB,此时SLB的timeout需要注意。比如SLB的timeout设置60s,而上方的proxy三个参数则是120s,此时如果nginx和后端的实际交互处理时长为90s。SLB等待nginx回复共计60s,nginx还未完成全部动作(因为文件传输需要90s),SLB等不及并认定nginx处理超时,主动断开连接,向client发出504(slb对客户端表示后端服务器处理太久了<其实slb只知道nginx太慢了>)。nginx自身的日志则会显示499的返回码,因为nginx的客户端(slb)主动断开了连接。