接口调用三方服务做异步数据清洗,但是怕把别人的服务调崩了,对接口加入Guava的限流策略
/**
* @author 寒夜
*/
@RestController
@Slf4j
public class Controller {
volatile RateLimiter rateLimiter = RateLimiter.create(10);
/**
* 非阻塞限流
*
* @param count 每秒消费的令牌个数 (每秒允许放行的请求次数)
* @return success/fail
*/
@GetMapping("/tryAcquire")
public String tryAcquire(Integer count) {
if (limiter.tryAcquire(count)) {
log.info("success,rate is {}", limiter.getRate());
return "success";
} else {
log.info("fail ,rate is {} ", limiter.getRate());
return "fail";
}
}
/**
* 限定时间的非阻塞限流
*
* @param count 每秒消费的令牌个数 (每秒允许放行的请求次数)
* @return success/fail
*/
@GetMapping("/tryAcquireWithTimeOut")
public String tryAcquireWithTimeOut(Integer count, Integer timeout) {
if (limiter.tryAcquire(count, timeout, TimeUnit.SECONDS)) {
log.info("success,rate is {}", limiter.getRate());
return "success";
} else {
log.info("fail ,rate is {} ", limiter.getRate());
return "fail";
}
}
/**
* 同步阻塞限流
* @param count 每秒消费的令牌个数 (每秒允许放行的请求次数)
* @return success
*/
@GetMapping("/acquire")
public String acquire(Integer count) {
limiter.acquire(count);
log.info("success,rate is {}", limiter.getRate());
return "success";
}
}
}
RateLimiter 在并发场景下使用是安全的,会限制所有线程的总速率,但是不保证公平。
以上是属于单机限流,分布式限流【Redisson RRateLimiter】:https://blog.csdn.net/truelove12358/article/details/127751211
我们会使用Semaphore、Guava 的 RateLimiter 等做一些并发量或速率的限流.但是单机的限流并不能扩大整体服务的阀值,比如访问或者操作DB的整体上限流或者某一批接口操作的限流,这种分布式可以保证服务集群整体上进行限流,并且可以忽略集群中流量划分不均衡的问题带来的细粒度限流控制,是一个不错的策略.
单机限流:
优点:
1.简单易实施:单机限流是在单个服务器上实现的,不需要复杂的架构和配置2.低延迟: 由于请求在单个服务器上进行处理,单机限流可以减少因网络通信带来的延迟。3.成本较低:相对于分布式限流而言,单机限流不需要额外的硬件和网络设施,成本较低。
缺点:
1.单点故障:如果限流措施仅部署在单个服务器上,那么一旦该服务器出现故障或不可用,整个系统将无法进行限流.2.扩展性有限:单机限流很难应对大规模请求的突发情况,无法提供高吞吐量和伸缩性。
分布式限流:
优点:
1.高可用性:由于限流策略分布在多个服务器上,即使其中一个服务器不可用,其他服务器仍然可以进行限流操作,保证系统的可用性。
2.横向扩展: 分布式限流提供了更好的扩展性,可以通过增加服务器数量来外理更大规模的请求,
3.灵活性:分布式限流可以根据不同服务器的负载情况进行动态调整,更好地适应系统的变化。
缺点:
1.复杂性: 分布式限流需要设计和实施复杂的架构,包括负载均衡、消息传递和协调等机制。2.高延迟:由于涉及多个服务器之间的通信,分布式限流可能引入较高的延迟,特别是在大规模请求的情况下