① 并发连接数
1)并发连接数 --> ('S'imultaneous 'B'rowser 'C'onnections) --> SBC
2)并发连接数指的是'客户端向服务器发起请求',并建立了'TCP连接',每秒钟服务器连接的'总TCP数量',就是'并发'连接数.
3)并发连接数是针对'tcp'连接而言的
场景:即使'tcp连接复用-->每个TCP上可能有多个HTTP请求',也是一个'连接'
4)换句话只要tcp连接没有断连,就'只是'一个连接
5)并发连接数的增大意味着对'系统内存资源'的消耗 -->消耗更多的'服务器资源'
② 并发请求数
1)请求数有'2个'缩写,可以叫'QPS'也可以叫'RPS'
备注:请求数-'QPS(Query Per Second')| RPS'(Request Per Second)'
2)单位是每秒多少请求;Query=查询,也相当于请求
3)请求数指的是客户端在'建立完连接'后,向http服务发出'GET/POST/HEAD'数据包个数 -->'HTTP连接'层面
模块作用:限制请求的'并发'连接数 --> 用来限制'同一时间'连接数
connection是连接: 即常说的'tcp连接'
nginx的所有'zone'都是'共享'内存
1)如果你限制一个客户端'最多1个'连接
2)但nginx上配了2个worker进程
3)那么即使该客户端发起2次连接分别'落在不同worker进程'上,也会'被拒绝'
+++++++++++++ 注意点 +++++++++++++
1)需要注意的是并'不是所有的连接'都会被算入其中
2)只有当一个连接的'整个请求头被读取'并且已经'被nginx服务器处理'的时候才会'算入限制'中
① limit_conn 重要
说明:每个'不同的用户'只能同时有'n个'连接到服务器
场景: 可以'临时开启'这个参数,验证是否是'限流'造成的'503'报错,此时'服务的调用'不会报错
备注: 注意内存'不要溢出'了
设置你所希望的日志级别:当服务器因为'频率过高拒绝'或者'延迟处理请求时可'以记下相应级别的日志
备注:'延迟'记录的日志级别比'拒绝'的'低'一个级别
说明: 默认打印到'error.log'的错误日志文件
思考:HTTP '503'和'429'错误码'高度相似',有时'该用哪个'竟然要商榷一下
默认:'503 Service Unavailable'
细节点:'不是所有'的状态码都可以使用,nginx官方'限定状态码'必须在'400到599'之间
⑤ limit_conn_zone 重要
++++++++'$binary_remote_addr'和'$remote_addr'的区别++++++++
优点: '压缩'内存占用量
1)$remote_addr变量的长度为'7字节到15字节',而存储状态在32位平台中占用32字节或64字节,在64位平台中占用64字节;
2)$binary_remote_addr变量的长度是'固定的4字节',存储状态在32位平台中占用32字节或64字节,在64位平台中占用64字节;
3)'1M共享空间'可以保存3.2万个32位的状态,1.6万个64位的状态;
4)如果'共享内存空间被耗尽',服务器将会对后续所有的请求'返回 503 '(Service Temporarily Unavailable) 错误;
5)思考常见的'key'形式? -->如何获取'客户端的真实ip'?
1)limit_conn_zone'只能够'在'http'块中使用
2)key就是用来判定'连接数的变量',这个变量可以是文本、变量或它们的组合
高级:'ip地址+cookie'等其他'复杂的组合'来更精确地'限定'范围
3)name就是这个'zone的命名',name需要'全局唯一'
4)size定义了'这个zone的大小',也就是nginx会在'内存中开辟多大'的空间来存储这个zone的相关信息,
备注:
[1]、主要和前面'定义的key'的大小有关系
[2]、需要'注意'的是,当'内存大小耗尽'的时候,nginx会直接'返回limit_conn_status定义错误码'给后续的请求
⑥ limit_zone 了解
size:基于'key',限制'多少'个并发连接数
应用场景: add_header Limit-Conn-Status $limit_conn_status; --> 观察是否'限流'
⑧ 案例讲
1)场景1: 'tcp连接数'超限,导致限流
2)场景2: 连接数不大,但是'zone'满了,导致限流
解读:如果'共享区域内存'耗尽,会对'所有请求'都返回错误
(1)案例
1)$binary_remote_addr: 意味着'对于每个 ip' 进行了连接数量的限制,并'不是对总的连接数'进行限制
备注: 限制的是'同一个ip'可以被nginx'同时处理'的请求数
2)limit_rate 50:表示每秒只发送50字节给客户端,所以'请求处理很慢',容易'触发'limit_conn的限制
备注: 实际生产环境下有'大量并发连接',不需要这样
limit_rate目的:限制给客户端的响应速度,导致tcp连接不中断,此时有新的连接建立,更'容易复现'限流
3)模拟:第一个请求还'未结束',第二个請求'又发起'的时候,此时并发连接数'为2'
备注:
方式1:) 使'响应速度'足够慢 -->'limit_rate'
方式2:) response body'特别大' -->'响应文件足够大'
4)注意'curl'和'浏览器'访问的一些区别
报错: nginx: [emerg] connection limit must be 'less 65536'
关联: /etc/security/limits.conf
(2)其它杂谈
1)不生效原因
实验环境如果是'内网',而且nginx'高性能'的处理效率,请求完成速度太快了;模拟的时候通过'响应速度'的角度来模拟
++++++++++++++++ '分割线' ++++++++++++++++
1)组网 client --> lvs('fullnat模式') --> nginx
细节点: 如果'nginx'没有安装toa模块,在生产环境中很容易触发'503'报错
2)解决策略
1)nginx设置'白名单'
2)nginx安装'toa'模块
⑨ 最佳实践
++++++++++++++"stream_control"++++++++++++++
limit_conn_zone $http_real_ip zone=conn:100m; # 1) 'http块'中定义
limit_conn conn 1000; # 2) 一般在server或者'location'中定义
说明:实际如果通过'UI'配置,可以通过 'include 配置文件'形式加载
作用:用来限制'tcp连接上单位时间内处理的请求数',即'速率'限制,采用的漏桶算法 "leaky bucket"
req:即request请求,是指'http请求'
作用:'启用'定义的限速参数
limit_req限流是按'时间片'来限流
1)burst
burst:相当于一个'缓存桶',当'请求的数量过多'时,'超出的请求'放入缓存区,当缓存'区达到上限'时,则返回错误
场景: 处理'突发'流量
客户感知:响应'变慢',但'不会被拒绝'
默认值:0
2)nodelay | delay number
1)'不使用nodelay','burst中'的请求会'延迟'处理
2)'使用'了nodealy,则'立刻返回失败'
3)二者是'互斥'的
3)多次使用
说明: 以'zone结尾'表示开辟的'共享内存',可以同时'被所有worker'进程使用
1)基本解读
2)官方案例
3)rate
常见单位:rate=1r/s 表示1秒钟一个请求、rate=2r/m 表示一分钟以内每间隔30秒一个请求
1)nginx可以实现'毫秒级别'的控制粒度
2)10r/s'等价'1r/100ms --> '每秒十个请求' --> 你调大'请求数',就相当于'调小了时间片'的单位
解读:在'没有'设置bursts的情况下,如果一个'请求接受处理之后'的'100ms内'出现第二个请求,那么它就会'被拒绝'处理
⑦ 限流算法
常见的'限流'算法:计数器、'漏桶'算法、'令牌桶'算法
(1)漏桶算法
(2)令牌算法
(3)限流的目的
⑧ 案例讲解
(1)案例1
++++++++++ "rate=2r/m"解读 ++++++++++
在'没有'设置burst的情况下,如果一个'请求接受处理之后'的'30内'出现第二个请求,那么它就会'被拒绝'处理
(2)案例2
(3)案例3
说明:不使用nodelay,burst中的请求会'延迟'处理,使用了nodealy,则'立刻返回'失败
(4)案例4
1)'不使用nodelay','burst中'的请求会'延迟'处理
2)'使用'了nodealy,则'立刻返回失败' --> 降低请求'时延'
(5)案例5
⑨ 最佳实践
++++++++++++++"stream_control"++++++++++++++
limit_req_zone $http_real_ip zone=req:100m rate=1000r/s; # 1) 'http块'中定义
limit_req zone=req burst=10000 nodelay; # 2) 一般在server或者'location'中定义
说明:实际如果通过'UI'配置,可以通过 'include 配置文件'形式加载
⑩ 思考
(1)优先级
说明: 通过返回的'状态码'来体会
细节点:reload后,共享内存'不会清空',所以之前的数据状态仍然会'影响'当前请求;通过'restart'保持实验环境的干净
1)细细体会
场景: 限制连接和限制请求'同时'打开
关键点:第'2'次请求
结论: limit_req在limit_con'之前'生效,导致'limit_con'没有机会处理
补充: 生产环境中limit_req和Limit_conn 这两者'都要'使用,它们限制的'目的'不同,可以'互补'
2) 对比实验
细节点: 配置burst=2之后,还是先被'limit_req(此时不会报错)'判断,之后还会进行'limit_con'判断
(2)特殊需求
(3)限速
limit_rate 50; 限制向用户返回的速率 每秒钟50个字节
nginx'认识'X-Accel-Rates 的响应头