我是靠谱客的博主 神勇墨镜,最近开发中收集的这篇文章主要介绍令牌桶和漏牌桶令牌桶漏牌桶区别:接入层限流(Nginx + Lua),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

参考:https://www.cnblogs.com/xuwc/p/9123078.html

令牌桶

令牌桶算法(Token Bucket):是网络流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一种算法。典型情况下,令牌桶算法用来控制发送到网络上的数据的数目,并允许突发数据的发送。

**算法思路:**令牌桶会以一定的速率生产令牌,直至装满。请求过来时先获取令牌,获取到的请求后台会接收并处理。没有获取到的请求会被抛弃,并返回429错误。
在这里插入图片描述

漏牌桶

漏桶算法(Leaky Bucket):主要目的是控制数据注入到网络的速率,平滑网络上的突发流量。漏桶算法提供了一种机制,通过它,突发流量可以被整形以便为网络提供一个稳定的流量。

**算法思路:**请求先进入到漏桶里,漏桶以一定的速度漏出请求,当用户请求过多时,他会存放在桶中,如果桶已经满了,请求溢出,返回503错误。

在这里插入图片描述

区别:

  • **实现思路区别:**令牌桶是按照固定速率往桶中添加令牌,请求是否被处理需要看桶中令牌是否足够,当令牌数减为零时则拒绝新的请求;漏桶则是按照常量固定速率流出请求,流入请求速率任意,当流入的请求数累积到漏桶容量时,则新流入的请求被拒绝;
  • **请求放行的区别:**令牌桶限制的是平均流入速率(允许突发请求,只要有令牌就可以处理,支持一次拿3个令牌,4个令牌),并允许一定程度突发流量;漏桶限制的是常量流出速率(即流出速率是一个固定常量值,比如都是1的速率流出,而不能一次是1,下次又是2),从而平滑突发流入速率;令牌桶允许一定程度的突发,而漏桶主要目的是平滑流入速率;

接入层限流(Nginx + Lua)

对于Nginx接入层限流可以使用Nginx自带了两个模块:连接数限流模块ngx_http_limit_conn_module和漏桶算法实现的请求限流模块ngx_http_limit_req_module。还可以使用OpenResty提供的Lua限流模块lua-resty-limit-traffic进行更复杂的限流场景。

ngx_http_limit_conn_module

limit_conn是对某个KEY对应的总的网络连接数进行限流。可以按照IP来限制IP维度的总连接数,或者按照服务域名来限制某个域名的总连接数。但是记住不是每一个请求连接都会被计数器统计,只有那些被Nginx处理的且已经读取了整个请求头的请求连接才会被计数器统计。

配置示例:

http {
limit_conn_zone$binary_remote_addr zone=addr:10m;
limit_conn_log_level error;
limit_conn_status 503;

server {

location /limit {
limit_conn addr 1;
}

limit_conn:要配置存放KEY和计数器的共享内存区域和指定KEY的最大连接数;此处指定的最大连接数是1,表示Nginx最多同时并发处理1个连接;

limit_conn_zone:用来配置限流KEY、及存放KEY对应信息的共享内存区域大小;此处的KEY是“ b i n a r y r e m o t e a d d r ” 其 表 示 I P 地 址 , 也 可 以 使 用 如 binary_remote_addr”其表示IP地址,也可以使用如 binaryremoteaddrIP使server_name作为KEY来限制域名级别的最大连接数;

limit_conn_status:配置被限流后返回的状态码,默认返回503;

limit_conn_log_level:配置记录被限流后的日志级别,默认error级别。

limit_conn的主要执行过程如下所示:

1、请求进入后首先判断当前limit_conn_zone中相应KEY的连接数是否超出了配置的最大连接数;

2.1、如果超过了配置的最大大小,则被限流,返回limit_conn_status定义的错误状态码;

2.2、否则相应KEY的连接数加1,并注册请求处理完成的回调函数;

3、进行请求处理;

4、在结束请求阶段会调用注册的回调函数对相应KEY的连接数减1。

ngx_http_limit_req_module

limit_req是漏桶算法实现,用于对指定KEY对应的请求进行限流,比如按照IP维度限制请求速率。

配置示例:

http {
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
limit_conn_log_level error;
limit_conn_status 503;

server {

location /limit {
limit_req zone=one burst=5 nodelay;
}

limit_req:配置限流区域、桶容量(突发容量,默认0)、是否延迟模式(默认延迟);

limit_req_zone:配置限流KEY、及存放KEY对应信息的共享内存区域大小、固定请求速率;此处指定的KEY是“$binary_remote_addr”表示IP地址;固定请求速率使用rate参数配置,支持10r/s和60r/m,即每秒10个请求和每分钟60个请求,不过最终都会转换为每秒的固定请求速率(10r/s为每100毫秒处理一个请求;60r/m,即每1000毫秒处理一个请求)。

limit_conn_status:配置被限流后返回的状态码,默认返回503;

limit_conn_log_level:配置记录被限流后的日志级别,默认error级别。

limit_req的主要执行过程如下所示:

1、请求进入后首先判断最后一次请求时间相对于当前时间(第一次是0)是否需要限流,如果需要限流则执行步骤2,否则执行步骤3;

2.1、如果没有配置桶容量(burst),则桶容量为0;按照固定速率处理请求;如果请求被限流,则直接返回相应的错误码(默认503);

2.2、如果配置了桶容量(burst>0)且延迟模式(没有配置nodelay);如果桶满了,则新进入的请求被限流;如果没有满则请求会以固定平均速率被处理(按照固定速率并根据需要延迟处理请求,延迟使用休眠实现);

2.3、如果配置了桶容量(burst>0)且非延迟模式(配置了nodelay);不会按照固定速率处理请求,而是允许突发处理请求;如果桶满了,则请求被限流,直接返回相应的错误码;

3、如果没有被限流,则正常处理请求;

4、Nginx会在相应时机进行选择一些(3个节点)限流KEY进行过期处理,进行内存回收。

lua-resty-limit-traffic

之前介绍的两个模块使用上比较简单,指定KEY、指定限流速率等就可以了,如果我们想根据实际情况变化KEY、变化速率、变化桶大小等这种动态特性,使用标准模块就很难去实现了,因此我们需要一种可编程来解决我们问题;而OpenResty提供了lua限流模块lua-resty-limit-traffic,通过它可以按照更复杂的业务逻辑进行动态限流处理了。其提供了limit.conn和limit.req实现,算法与nginx limit_conn和limit_req是一样的。

最后

以上就是神勇墨镜为你收集整理的令牌桶和漏牌桶令牌桶漏牌桶区别:接入层限流(Nginx + Lua)的全部内容,希望文章能够帮你解决令牌桶和漏牌桶令牌桶漏牌桶区别:接入层限流(Nginx + Lua)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(56)

评论列表共有 0 条评论

立即
投稿
返回
顶部