JAVA和Nginx 教程大全

网站首页 > 精选教程 正文

分布式限流的应用 分布式降级限流

wys521 2024-10-27 15:40:42 精选教程 27 ℃ 0 评论

我们在前面限流算法中提到了几种限流方式,但仅限在单节点应用中使用。在集群环境中或者分布式应用服务中,如何保证资源的并发限流控制呢?有两种限流思路:

  • 应用层限流:这种限流贴近业务,使用灵活。

  • 接入层限流:从流量入口设卡,负载均衡请求、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限流模块。

本文是分布式限流的基础,也是灵魂。大家在工作中应该会遇到与业务相关性强的限流,大家根据实际业务变通下。希望本文可以帮到你。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表