在开发高并发系统时有三把利器用来保护系统:缓存、降级和限流
- 缓存 缓存的目的是提升系统访问速度和增大系统处理容量 (本地, redis)
- 降级 降级是当服务出现问题或者影响到核心流程时,需要暂时屏蔽掉,待高峰或者问题解决后再打开 (hystrix)
- 限流 限流的目的是通过对并发访问/请求进行限速,或者对一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务、排队或等待、降级等处理 (令牌桶算法)
令牌桶算反简介
令牌桶算法原理如下:用户请求必须拿到令牌才代表消费成功。而“令牌数”有一个初始值,令牌桶也有一个令牌存储上限,当桶中的令牌耗光后,令牌桶会以自定义的速度生产令牌,此时所有的水(用户请求)会进入阻塞状态,阻塞时间内如果得到了令牌就会消费成功,如果阻塞时间过了还没有得到令牌,请求会被抛弃。
限流方式有很多种:
- Tomcat限流
- nginx限流
- 服务器端配合限流
单机版限流 - RateLimiter 谷歌 / 线程安全
参考连接
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.2-jre</version>
</dependency>
private static RateLimiter rateLimiter = RateLimiter.create(100); // 100QPS/s
@GetMapping("kill")
public String sale() {
if (!rateLimiter.tryAcquire(0, TimeUnit.MILLISECONDS)) {
return "服务太忙了";
}
// 业务逻辑
return "牛啊";
}
// 模拟 线上可不这么写...
// 200请求/s
for (int i = 0; i < 200; i++) {
new Thread(() ->{
System.out.println(HttpUtil.get("http://localhost:8080/kill"));
}).start();
}
分布式限流 - Sentinel 阿里巴巴 ******
Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景 (他们自己说的)
挺牛逼的开源项目
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.1</version>
</dependency>
// 定义规则
private void initFlowQpsRule() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule("kill-");
// set limit qps to 20
rule.setCount(20);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setLimitApp("default");
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
// 接口
initFlowQpsRule();
try (Entry entry = SphU.entry("kill-")) {
// 被保护的业务逻辑
// do something here...
return "牛啊";
} catch (BlockException ex) {
// 资源访问阻止,被限流或被降级
// 在此处进行相应的处理操作
return "等等吧, 太忙了";
}
Redis实现分布式限流
https://blog.csdn.net/weixin_44912855/article/details/120667603?spm=1001.2014.3001.5501