我们还是通过50并发循环10次访问。我们可以发现只有在一开始能达到比较高的吞吐量。在随后桶的容量满了之后。而下游水滴速率比上游请求速率慢的情况下。只能以下游恒定的速度接收访问。
他的问题也暴露的很明显。针对时间窗口的不足漏桶进行的不足,但是仍是不足。无法彻底避免请求溢出的问题。
请求溢出本身就是一种灾难性的问题。所有的算法目前都没有解决这个问题。只是在减缓他带来的问题
令牌桶算法
令牌桶和漏桶法是一样的。只不过将桶的作用方向改变了一下。
漏桶的出水速度是恒定的,如果流量突然增加的话我们就只能拒绝入池
但是令牌桶是将令牌放入桶中,我们知道正常情况下令牌就是一串字符当桶满了就拒绝令牌的入池,但是面对高流量的时候正常加上我们的超时时间就留下足够长的时间生产及消费令牌了。这样就尽可能的不会造成请求的拒绝
最后,不论是对于令牌桶拿不到令牌被拒绝,还是漏桶的水满了溢出,都是为了保证大部分流量的正常使用,而牺牲掉了少部分流量
public Map<string, object=""> startLingpaitong(Map<string, object=""> paramMap) { String redisKey = "lingpaitong"; String token = redisTemplate.opsForList().leftPop(redisKey).toString(); //正常情况需要验证是否合法,防止篡改 if (StringUtils.isEmpty(token)) { throw new RuntimeException("令牌桶拒绝"); } Map<string, object=""> map = new HashMap<>(); map.put("success", "success"); return map; } @Scheduled(cron="*/1 * * * * ?") private void process(){ //一次性生产两个 System.out.println("正在消费。。。。。。"); for (int i = 0; i < 2; i++) { redisTemplate.opsForList().rightPush(redisKey, i); } }</string,></string,></string,></string,></string,></string,></string,></string,object></string,></string,></string,object></string,></string,></string,></string,></string,object>