美文网首页
Java应用限流

Java应用限流

作者: f0cf20ca7354 | 来源:发表于2019-07-19 16:01 被阅读0次

在开发高并发系统时,有三把利器用来保护系统:缓存、降级和限流:
缓存:缓存的目的是提升系统访问速度和增大系统处理容量
降级:降级是当服务出现问题或者影响到核心流程时,需要暂时屏蔽掉,待高峰或者问题解决后再打开
限流:限流的目的是通过对并发访问/请求进行限速,或者对一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务、排队或等待、降级等处理

常见算法:
1、计时器限流
2、滑动窗口
3、漏桶算法
4、令牌桶算法

计时器限流

计时器是限流算法中比较简单的一种算法,比如:限制一个接口1分钟内不能超过100次请求,可以在一开始设置一个计数器,每当接收到请求时,将计数器加1,如果计数器的值大于100并且当前请求与第一个请求的执行时间间隔还在1分钟内的,那就说明请求过多;如果当前请求与第一次请求的时间间隔超过1分钟,并且请求次数没有超限的,那么重置计数器

import org.springframework.data.redis.core.RedisTemplate;
/**
 * 计数器限流
 * 限制1分钟内请求100次
 * 弊端:
 * 1、当前窗口100个请求全部集中到结束点,下个窗口100个请求全部集中到起始点,临界点就会出现请求暴增的情况,可能瞬间压垮应用
 * 2、只适用于单机应用,分布式环境中无法满足
 *
 * @author lile
 * @date 2019/7/1618:59
 */
public class CounterLimit {

    //时间窗口内的最大请求数
    public final int reqCount = 100;

    //时间窗口内的当前请求数
    private int currentReqCount;

    //时间窗口的长度  单位:ms
    public final int interval = 60 * 1000;

    //当前时间
    public Long currentTimestamp = System.currentTimeMillis();

    public RedisTemplate redisTemplate;

    public final String key = "minute_test";

    /**
     * 计数器限流
     *
     * @return
     */
    public boolean grant() {
        Long nowTimestamp = System.currentTimeMillis();
        if (nowTimestamp < currentTimestamp + interval) {
            //在当前时间窗口内
            currentReqCount++;
            //判断当前时间窗口的请求数是否小于最大的请求限制数
            return currentReqCount < reqCount;
        }
        //不在当前窗口内时,重置下个窗口的首次请求时间及窗口内请求数
        currentReqCount = 1;
        currentTimestamp = nowTimestamp;
        return true;
    }

    /**
     * 滑动窗口的限流
     * 保证时间窗口中的请求数不超过最大限制数即可,能平稳的控制请求的速率,请求过快会被拒绝
     * 窗口时间范围定为1分钟,每次接收到请求后重新划分时间窗口,当前时间往前的1分钟范围为新的时间窗口
     *
     * @return
     */
    public boolean DuoJiQi() {
        Long nowTimestamp = System.currentTimeMillis();
        if (redisTemplate.opsForZSet().size(key) > 0) {
            //移除不在当前时间窗口的数据
            redisTemplate.opsForZSet().removeRangeByScore(key, 0, nowTimestamp - interval);
        } 
        redisTemplate.opsForZSet().add(key, "当前请求的唯一ID", nowTimestamp);
        if (redisTemplate.opsForZSet().size(key) > reqCount) {
            //请求超限,禁止提交请求
            return false;
        }
        return true;
    }
}

滑动窗口

相关文章

  • Java应用限流

    在开发高并发系统时,有三把利器用来保护系统:缓存、降级和限流:缓存:缓存的目的是提升系统访问速度和增大系统处理容量...

  • Java高并发-应用限流

    限流 限流的目的是通过对并发访问/请求进行限速或者一个时间窗口内的的请求进行限速来保护系统,一旦达到限制速率则可以...

  • 限流降级方案

    限流算法 并发数限流 计数器并发数限流:使用共享变量实现 信号量:使用java中的Semaphore QPS限流 ...

  • 180613-GuavaCache返回Null的注意事项

    GuavaCache返回Null的注意事项 Guava在实际的Java后端项目中应用的场景还是比较多的,比如限流,...

  • 高并发环境下的限流策略

    本文将从以下几个方面分析限流策略: 什么是限流限流算法限流算法的应用 什么是限流 在开发高并发系统时,有很多手段来...

  • 聊聊高并发系统之限流特技-2

    摘要:上一篇《聊聊高并发系统限流特技-1》讲了限流算法、应用级限流、分布式限流;本篇将介绍接入层限流实现。 接入层...

  • 聊聊高并发系统限流特技-2

    转载来自开涛的聊聊高并发系统限流特技-2 上一篇《聊聊高并发系统限流特技-1》讲了限流算法、应用级限流、分布式限流...

  • 接口限流处理

    每个API接口都有自己的访问极限,实现接口限流,保护应用以及服务器的正常运行。方式一: Java处理令牌桶处理:(...

  • 分布式限流

    前言 本文接着上文应用限流进行讨论。 之前谈到的限流方案只能针对于单个 JVM 有效,也就是单机应用。而对于现在普...

  • 分布式限流的方案

    前言 本文接着上文应用限流进行讨论。 之前谈到的限流方案只能针对于单个 JVM 有效,也就是单机应用。而对于现在普...

网友评论

      本文标题:Java应用限流

      本文链接:https://www.haomeiwen.com/subject/zalxlctx.html