为何有这篇文章
在负责某个项目开发过程当中,在定时任务(job)里面调用了公司的内部某个微服务,进行财务流水生成,在被调用方能力处理不及时的时候,引起被调用方宕机奔溃,故此在客户端,即Job作简单的限流,因而针对此场景进行调研,发现Guava RateLimiter在此种场景下,简单且高效。
模拟调用示例
public static void main(String[] args) {
// 模拟10次调用
int a = 10;
while (true) {
// 调用的当前时间
LocalTime now = LocalTime.now();
System.out.println("模拟调用三方微服务,当前时间为:" + now.toString());
a--;
if (a == 0) {
break;
}
}
}
模拟调用三方微服务,当前时间为:10:16:22.088
模拟调用三方微服务,当前时间为:10:16:22.089
模拟调用三方微服务,当前时间为:10:16:22.089
模拟调用三方微服务,当前时间为:10:16:22.089
模拟调用三方微服务,当前时间为:10:16:22.089
模拟调用三方微服务,当前时间为:10:16:22.089
模拟调用三方微服务,当前时间为:10:16:22.089
模拟调用三方微服务,当前时间为:10:16:22.089
模拟调用三方微服务,当前时间为:10:16:22.089
模拟调用三方微服务,当前时间为:10:16:22.089
由本示例能够了解到,在 10:16:22 内完成了 10次调用,本次调用过程当中对于调用方的并发处理能力要求很高,若是调用方没有作限流等操做的话,在业务高峰期,调用方很容易崩溃,固然咱们若是做为调用方的话,也须要作简单的限流操做:推荐使用 sentine
https://sentinelguard.io/zh-cn/docs/open-source-framework-integrations.html
客户端调用按照RateLimiter限流限流示例
public static void main(String[] args) {
//初始化 每秒1个令牌
RateLimiter rateLimiter = RateLimiter.create(1);
int a = 10;
while (true) {
//每次须要1个令牌
rateLimiter.acquire(1);
LocalTime now = LocalTime.now();
System.out.println("模拟调用三方微服务,当前时间为:" + now.toString());
a--;
if (a == 0) {
break;
}
}
}
模拟调用三方微服务,当前时间为:10:24:10.257
模拟调用三方微服务,当前时间为:10:24:11.176
模拟调用三方微服务,当前时间为:10:24:12.177
模拟调用三方微服务,当前时间为:10:24:13.177
模拟调用三方微服务,当前时间为:10:24:14.180
模拟调用三方微服务,当前时间为:10:24:15.180
模拟调用三方微服务,当前时间为:10:24:16.175
模拟调用三方微服务,当前时间为:10:24:17.180
模拟调用三方微服务,当前时间为:10:24:18.179
模拟调用三方微服务,当前时间为:10:24:19.177
咱们能够看到限流后的服务调用记录,在10-19秒内,每秒调用一次,服务调用平稳,并没有瞬时的高峰,缓解了调用方的服务压力,不会平白无故背锅。
RateLimiter源码分析
持续更新中....