Java并发编程入门(十一)限流场景和Spring限流器实现

本文介绍了限流场景,通常基于CPU、内存和IO负载,适用于动态增加资源的情况。文章详细阐述了如何在Spring中实现限流,包括限流需求、相关类结构,并提供了代码示例进行验证。最后提到了去掉同步锁后的并发行为和限流资源的管理。
摘要由CSDN通过智能技术生成

一、限流场景

限流场景一般基于硬件资源的使用负载,包括CPU,内存,IO。例如某个报表服务需要消耗大量内存,如果并发数增加就会拖慢整个应用,甚至内存溢出导致应用挂掉。

限流适用于会动态增加的资源,已经池化的资源不一定需要限流,例如数据库连接池,它是已经确定的资源,池的大小固定(即使可以动态伸缩池大小),这种场景下并不需要通过限流来实现,只要能做到如果池内链接已经使用完,则无法再获取新的连接则可。

因此,使用限流的前提是:

1.防止资源使用过载产生不良影响。

2.使用的资源会动态增加,例如一个站点的请求。

二、Spring中实现限流

I、限流需求

1.只针对Controller限流

2.根据url请求路径限流

3.可根据正则表达式匹配url来限流 4.可定义多个限流规则,每个规则的最大流量不同

II、相关类结构

 

 

1.CurrentLimiteAspect是一个拦截器,在controller执行前后执行后拦截

2.CurrentLimiter是限流器,可以添加限流规则,根据限流规则获取流量通行证,释放流量通行证;如果获取通行证失败则抛出异常。

3.LimiteRule是限流规则,限流规则可设置匹配url的正则表达式和最大流量值,同时获取该规则的流量通信证和释放流量通信证。

4.AcquireResult是获取流量通信证的结果,结果有3种:获取成功,获取失败,不需要获取。

5.Application是Spring的启动类,简单起见,在启动类种添加限流规则。III、Show me code

1.AcquireResult.java

public class AcquireResult {
 /** 获取通行证成功 */
 public static final int ACQUIRE_SUCCESS = 0;
 /** 获取通行证失败 */
 public static final int ACQUIRE_FAILED = 1;
 /** 不需要获取通行证 */
 public static final int ACQUIRE_NONEED = 2;
 /** 获取通行证结果 */
 private int result;
 /** 可用通行证数量 */
 private int availablePermits;
 public int getResult() {
 return result;
 }
 public void setResult(int result) {
 this.result = result;
 }
 public int getAvailablePermits() {
 return availablePermits;
 }
 public void setAvailablePermits(int availablePermits) {
 this.availablePermits = availablePermits;
 }
}

2.LimiteRule.java

/**
 * @ClassName LimiteRule
 * @Description TODO
 * @Author 铿然一叶
 * @Date 2019/10/4 20:18
 * @Version 1.0
 * javashizhan.com
 **/
public class LimiteRule {
 /** 信号量 */
 private final Semaphore sema;
 /** 请求URL匹配规则 */
 private final String pattern;
 /** 最大并发数 */
 private final int maxConcurrent;
 public LimiteRule(String pattern, int maxConcurrent) {
 this.sema = new Semaphore(maxConcurrent);
 this.pattern = pattern;
 this.maxConcurrent = maxConcurrent;
 }
 /**
 * 获取通行证。这里加同步是为了打印可用通行证数量时看起来逐个减少或者逐个增加,无此打印需求可不加synchronized关键字
 * @param urlPath 请求Url
 * @return 0-获取成功,1-没有获取到通行证,2-不需要获取通行证
 */
 public synchronized AcquireResult tryAcquire(String urlPath) {
 AcquireResult acquireResult = new AcquireResult();
 acquireResult.setAvailablePermits(this.sema.availablePermits());
 try {
 //Url请求匹配规则则获取通行证
 if (Pattern.matches(pattern, urlPath)) {
 boolean acquire =
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值