网站首页 > 精选教程 正文
我们在前面限流算法中提到了几种限流方式,但仅限在单节点应用中使用。在集群环境中或者分布式应用服务中,如何保证资源的并发限流控制呢?有两种限流思路:
应用层限流:这种限流贴近业务,使用灵活。
接入层限流:从流量入口设卡,负载均衡请求、ACL控制等请求过滤,一般使用HAProxy或者Nginx实现。
因为最近我分享的文章穿插着限流技术和分布式事务锁,这两者是有本质区别的,例如:
限流:保护服务防止被击垮,牺牲了用户体验保服务的做法。
事务锁:防止高并发访问破坏事务一致性,保证业务的准确性。
应用层限流
单节点应用的限流,对限流资源保护入口是唯一的,例如前面我们介绍使用Guava的RateLimiter就可以实现。
单节点限流
在集群或者分布式应用环境中,由于使用了负载均衡,存在多节点共同访问资源的情况,所以需要引入分布式限流方式。如下图,我们把应用中的限流抽取出来,单独形成分布式限流服务:
分布式限流
分布式限流中,我们要注意需要将限流服务做成原子性操作。Lua脚本本身可实现复杂的编程,可以很方便实现限流算法,而Redis又是单线程模式,所以很适合用来实现限流服务。我们先看下Redis+lua脚本实现的代码demo示例:
Lua脚本文件内容如下:
lua script demo
JAVA代码:
java code demo
接入层限流
A、我们先看下Nginx的限流说明
nginx限流模块
接入层是指流量的入口,使用HAProxy或者Nginx都可以实现,接入层具有负载均衡、ACL过滤、缓存、限流的功能。对于Nginx接入层限流,我们可以采用它自带的两个模块,分别是:
ngx_http_limit_conn_module:连接数限流模块,用来对每一个key对应的总连接数进行控制,例如限制一个IP或域名的总连接数。注意,并非每一个连接都被计数,只有当请求被server处理了并且请求头已经完全被nginx server读取之后,此连接才被计数。
ngx_http_limit_req_module:漏桶算法实现模块,用来对每个key对应的请求速率进行控制,例如控制来自一个IP的请求速率,限流模式分为平滑模式和允许突发模式。
ngx_http_limit_conn_module配置示例
并发限制1个请求
limit_conn:配置存放key和counter的共享内存区域,指定最大连接数。
limit_conn_zone:(语法是limit_conn_zone key zone=name:size;)用来配置存放key以及对应信息的共享内存区域大小。上例中key就是ipv4地址。
limit_conn_status:限流后返回503。
ngx_http_limit_req_module配置示例
nodelay限流
limit_req:配置限流区域,桶大小,延迟模式
limit_req_zone:配置key以及存放key对应信息的共享内存大小和固定请求速率。同limit conn,key是一个IPV4地址。
B、HAProxy的限流使用说明
HAProxy早期是不支持限流的,作者后来新增的功能,用起来实际并没有Nginx清晰,我们大概看下HAProxy配置思路,例如frontend配置:
stick-table type ip size 200k expire 10m store gpc0
acl whitelist src 192.168.1.154
acl source_is_abuser src_get_gpc0(http) gt 0
use_backend ease-up-y0 if source_is_abuser
tcp-request connection track-sc1 src if ! source_is_abuser
首先要声明一个具有200K长度的table,用来存储ip地址。expire参数则表示该IP在table中的过期时间。然后我们启用跟踪并设置限流参数,例如在backend:
stick-table type ip size 200k expire 3m store conn_rate(100s),bytes_out_rate(60s)
tcp-request content track-sc2 src
acl conn_rate_abuse sc2_conn_rate gt 5
acl data_rate_abuse sc2_bytes_out_rate gt 20000000
最后我们启用规则:
acl mark_as_abuser sc1_inc_gpc0 gt 0
tcp-request content reject if conn_rate_abuse !whitelist mark_as_abuser
tcp-request content reject if data_rate_abuse !whitelist mark_as_abuser
上面看到两款软件的限流,实际上Nginx使用起来比较清晰,额,个人观点,勿喷,实际上我们项目使用的是HAProxy。
总结
我们掌握了Guava的RateLimiter,可以单节点限流。
限流分为业务限流和接入层限流。
Nginx两个限流模块的使用,有兴趣去看下OpenResty提供的Lua限流模块。
本文是分布式限流的基础,也是灵魂。大家在工作中应该会遇到与业务相关性强的限流,大家根据实际业务变通下。希望本文可以帮到你。
猜你喜欢
- 2024-10-27 web中间件应用系列:负载均衡(一)什么是负载均衡?
- 2024-10-27 运维工程师面试题总结与分享 运维工程师面试技巧和注意事项
- 2024-10-27 生产环境中使用ngrok:不仅仅用于测试
- 2024-10-27 Haproxy 基础 haproxy配置文件详解
- 2024-10-27 nice服务端架构重构与演进 nice平台客服入口
- 2024-10-27 精心整理了近5年大厂面试题!涉及22个技术点,限时分享,速领
- 2024-10-27 负载均衡的不同方案 负载均衡类型选择
- 2024-10-27 在 Linux 中如何使用 HAProxy、Nginx 和 Keepalived 进行负载均衡?
- 2024-10-27 微服务架构下的高可用和高性能设计
- 2024-10-27 haproxy 特性说明 haproxy原理详解
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)