您现在的位置是:亿华云 > 人工智能
SpringBoot项目中接口限流实现方案
亿华云2025-10-09 15:33:11【人工智能】5人已围观
简介限流算法一般有漏桶算法和令牌桶算法及计数器三种方式。计数器用计数器实现限流有点简单粗暴,一般我们会限 制一秒钟的能够通过的请求数,比如限流QPS为100,算法的实现思路就是从第一个请求进来开始计时,在
限流算法
一般有漏桶算法和令牌桶算法及计数器三种方式。项目现方
计数器
用计数器实现限流有点简单粗暴,中接一般我们会限 制一秒钟的口限能够通过的请求数,比如限流QPS为100,流实算法的项目现方实现思路就是从第一个请求进来开始计时,在接下去的中接1s内,每来一个请求,口限就把计数加1,流实如果累加的项目现方数字达到了100,那么后续的中接请求就会被全部拒绝。等到1s结束后,口限把计数恢复成0,流实重新开始计数。项目现方
具体的中接实现可以是这样的:对于每次服务调用,可以通过 AtomicLong#incrementAndGet()方法来给计数器加1并返回最新值,口限通过这个最新值和阈值进行比较。
这种实现方式,有一个弊端:如果我在单位时间1s内的前10ms,已经通过了100个请求,那后面的990ms,只能眼巴巴的把请求拒绝,b2b信息网我们把这种现象称为“突刺现象”。
漏桶算法
漏桶算法主要是控制数据注入到网络的速率,平滑网络上的突发流量。漏桶算法提供了一种机制,通过它,突发流量可以被整形以便为网络提供一个稳定的流量。
漏桶可以看作是一个带有常量服务时间的单服务器队列,如果漏桶(包缓存)溢出,那么数据包会被丢弃。 在网络中,漏桶算法可以控制端口的流量输出速率,平滑网络上的突发流量,实现流量整形,从而为网络提供一个稳定的流量。
如图所示,把请求比作是水,水来了都先放进桶里,并以限定的速度出水,当水来得过猛而出水不够快时就会导致水直接溢出,即拒绝服务。
image
可以看出,漏桶算法可以很好地控制流量的企商汇访问速度,一旦超过该速度就拒绝服务。
令牌桶算法
令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。从原理上看,令牌桶算法和漏桶算法是相反的,一个“进水”,一个是“漏水”。
image
了解完后3种限流算法后,接下来我们看看在项目中如何应用。
使用Google Guava库RateLimiterRateLimiter使用的是一种叫令牌桶的流控算法,RateLimiter会按照一定的频率往桶里扔令牌,线程拿到令牌才能执行;且RateLimiter不支持集群环境,集群环境需要借助Redis等第三方工具实现。
依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>30.1.1-jre</version> </dependency>实现目标:每秒只允许3个请求通过。
@RestController @RequestMapping("/products") public class ProductController { private final RateLimiter rateLimiter = RateLimiter.create(5.0) ; @GetMapping("/{ id}") public ResponseEntity<R> queryProducts(@PathVariable("id") String id) throws Exception { if (rateLimiter.tryAcquire(1)) { TimeUnit.MILLISECONDS.sleep(200) ; return new ResponseEntity<R>(R.success("查询商品【" + id + "】成功"), HttpStatus.OK) ; } return new ResponseEntity<R>(R.failure("你访问的太快了"), HttpStatus.INTERNAL_SERVER_ERROR) ; } }通过Jmeter测试,版本5.4.1
线程配置,100个并发循环2次
接口配置
测试结果
RateLimiter相关方法说明:
参考https://ifeve!com/guava-ratelimiter
使用百度的ratelimiter-spring-boot-starterratelimiter-spring-boot-starter为服务端限流的免费信息发布网SDK,提供单节点维度的限流功能,通过限流算法,在流量过大时保证服务端按照一定速率平滑处理请求。
基于Spring Boot框架开发,目的是为Spring Cloud项目增加限流功能,同样在Spring Boot项目中也能正常使用。 本Starter的目前的应用场景为在Spring Cloud/Spring Boot的Web项目中引入该限流Starter,配置限流规则开启限流功能。 非Spring Web项目的特性正在规划中。
限流维度为:节点级、方法维度、服务维度限流。
节点级别含义为限流SDK引入目标服务代码,限流规则针对目标服务部署的每个实例单独生效。 方法维度含义为可以为目标服务的每个方法单独配置限流规则,该规则针对当前方法生效,与其他方法互不影响,目前方法仅支持HttpMethod+uri。 服务维度含义为可针对每个服务实例配置全局规则,流入该服务实例的每个请求都将先进行服务限流判断。 服务级和方法级同时存在,将先后进过服务级、方法级两种限流器,任意一个限流器拒绝都将拒绝请求。目前方法级只提供http方法的规则配置与生效,后续有计划支持Rpc方法的限流。
依赖
<dependency> <groupId>com.baidubce.formula</groupId> <artifactId>ratelimiter-spring-boot-starter</artifactId> <version>2.1.1.1</version> </dependency>应用配置
spring: application: name: ratelimiter --- formula: ratelimiter: enabled: true ratelimiters: # 限流生效的位置,配置具体的uri - effectiveLocation: /products/q/** # 限流类型:1表示http,2表示rpc(暂未支持) effectiveType: 1 # 该规则是否生效 enabled: true httpMethod: GET # 限流器类型,1表示令牌桶 limiterType: 1 # 请求来源,当前版本不区分请求来源,区分请求来源的需求正在开发 # source: # 限流的QPS值 threshold: 5注意:这里的spring.application.name必须配置,不然启动报错;
formula.ratelimiter.ratelimiters.source这个没有搞懂怎么配置的,官方文档没找到。
接口
@GetMapping("/q/{ id}") public ResponseEntity<R> queryProduct(@PathVariable("id") String id) throws Exception { TimeUnit.MILLISECONDS.sleep(200) ; return new ResponseEntity<R>(R.success("查询商品【" + id + "】成功"), HttpStatus.OK) ; }测试
对于失败的请求,返回状态码429(Too Many Request)
baidu的这个限流工具,核心过滤器:
RateLimiterEffectiveFilter.java
waitForPermit方法
waitForPermission方法
HttpUtil#isBlockException方法
看到这里你想修改返回信息只能是重写它的代码了。
重写该类:
在我们项目src新建
com.baidu.formula.ratelimiter.spring.boot.autoconfigure.util.HttpUtil类修改isBlockException方法
public static boolean isBlockException(HttpServletResponse response, Exception e) throws IOException { if (e instanceof BlockException) { response.setStatus(429); // too many request response.setContentType("application/json; charset=utf-8"); response.setCharacterEncoding("UTF-8"); response.getWriter().print("{ \"code\": -1, \"message\": \"你的请求太快了\"}") ; response.flushBuffer(); return true; } else { return false; } }测试:
完毕!!!
很赞哦!(3259)
上一篇: 国际域名转移的费用和处理步骤是什么?
相关文章
- 4、域名传输时,取决于域名原始用户的邮箱是否有效,以及他是否将密码发送到此邮箱。
- 那些被关停的平台域名如何了?有什么好的前景?
- 新企业更换域名应该怎么做?有哪些细节需要注意?
- 为什么说优质域名让企业获益良多?什么原因?
- .net 适用于从事Internet相关的网络服务的机构或公司
- 线上营销需要域名吗?线上域名的效果怎样?
- 宝洁公司拥有什么极品域名?盘点宝洁公司域名那些事
- 新手对域名的选择注意哪几点?有什么因素影响?
- 投资各类域名就像到处打游击战,结果处处失败。因为这样,对任何一个中国域名市场的走势和价格都没有准确的把握,所以最好缩小范围,准确把握战场态势,埋伏。
- 三拼域名有市场吗?盘点三拼域名有哪些融资的终端?