java 限流方式

  1. image.png
  2. Java中的流量限制方式;
    • 容器限流:常用的有tomcat容器最大线程数,最大连接数,nginx限制ip的链接和并发等
      • tomcat参数配置
      • backlog:当所有可能的请求处理县曾都在使用时,队列中排队的请求最大数目,默认为10,当队列已满,任何请求都将被拒绝
      • maxSpareThread:允许存在空闲线程的最大数目,默认值为50
      • maxThreads:最大线程书,默认值200
      • minSpareThreads:设当连接器第一次启动时创建线程的数目,确保至少有这么多的空闲线程可用,默认为4
      • Port:服务端套接字的TCP端口号,默认值8089
      • topDoDelay:为true时,可以提高性能,默认值为true
      • soTimeout:超时值
      • nginx限流:
        • httplimit zone 参数配置
        • limit_conn zone_name the_size 默认值为0 作用域:http,server,location ; 指定一个会话最大的并发连接数,当超过指定的最大并发连接数时,服务器将返回“Service unavailable”(503)
        • 定义一个叫one的记录区,总容量为10M,以变量$binary_remote_addr作为会话的判断基准(即一个地址一个会话),限制/download/目录下,一个会话只能进行一个连接,就是限制该目录下,一个ip只能发起一个连接,躲过一个,一律503
        • limit_req_zone参数配置:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ms9m3GmR-1602677557861)(https://i.loli.net/2020/09/19/13oAx7rS4J9OpVK.png)]:$binary_remote_addr:表示根据客户端ip限制;zone=one:10m:生成10m空间,命名为one,用于存储访问频率:rate=1r/s:意思是限制相同ip每秒访问频次,这里是1s/次
    • 限制总的资源数
    • 限制接口的请求的总并发数/请求数
    • Guava实现限流:
      • Guava是谷歌开源的java库,里面对于封装了一些常用的类库,是对JDK的扩展延伸丰富,它里边的RateLimite类,提供了令牌桶算法的实现:平滑突发限流和平滑预热限流实现
/**
 * 平滑突发限流(SmoothBursty)
 */
public class SmoothBurstyRateLimitTest {
    public static void main(String[] args) {
        //QPS = 5,每秒允许5个请求
        RateLimiter limiter = RateLimiter.create(5);
        //limiter.acquire() 返回获取token的耗时,以秒为单位
        System.out.println(limiter.acquire());
        System.out.println(limiter.acquire());
        System.out.println(limiter.acquire());
        System.out.println(limiter.acquire());
        System.out.println(limiter.acquire());
        System.out.println(limiter.acquire());
    }
}

/**
 * 平滑突发限流(smoothbursty)
 */
public class SmoothBurstyRateLimitTest02 {
 
    public static void main(String[] args) {
        //每秒允许5个请求,表示桶容量为5且每秒新增5个令牌,即每隔0.2毫秒新增一个令牌
        RateLimiter limiter = RateLimiter.create(5);
        //一次性消费5个令牌
        System.out.println(limiter.acquire(5));
        //limiter.acquire(1)将等待差不多1秒桶中才能有令牌
        System.out.println(limiter.acquire(1));
        //固定速率
        System.out.println(limiter.acquire(1));
        //固定速率
        System.out.println(limiter.acquire(1));
        //固定速率
        System.out.println(limiter.acquire(1));
    }
}

 

/**
 * 平滑突发限流(smoothbursty)
 */
public class SmoothBurstyRateLimitTest03 {
 
    public static void main(String[] args) {
        //每秒允许5个请求,表示桶容量为5且每秒新增5个令牌,即每隔0.2毫秒新增一个令牌
        RateLimiter limiter = RateLimiter.create(5);
        //第一秒突发了10个请求
        System.out.println(limiter.acquire(10));
        //limiter.acquire(1)将等待差不多2秒桶中才能有令牌
        System.out.println(limiter.acquire(1));
        //固定速率
        System.out.println(limiter.acquire(1));
        //固定速率
        System.out.println(limiter.acquire(1));
        //固定速率
        System.out.println(limiter.acquire(1));
    }
}

平滑预热限流:

/**
 * 平滑预热限流(SmoothWarmingUp)
 */
public class SmoothWarmingUp {
    public static void main(String[] args) {
        //permitsPerSecond:每秒新增的令牌数  warmupPeriod:从冷启动速率过渡到平均速率的时间间隔
        //系统冷启动后慢慢的趋于平均固定速率(即刚开始速率慢一些,然后慢慢趋于我们设置的固定速率)
        RateLimiter limiter = RateLimiter.create(10, 1000, TimeUnit.MILLISECONDS);
        for(int i = 0; i < 10;i++) {
            //获取一个令牌
            System.out.println(limiter.acquire(1));
        }
    }
}

guava 秒杀场景的实现
public class MiaoShaTest {
 
    public static void main(String[] args) throws InterruptedException {
        //限流,每秒允许10个请求进入秒杀
        RateLimiter limiter = RateLimiter.create(10);
        for (int i = 0; i < 100; i++) {
            //100个线程同时抢购
            new Thread(() -> {
                //每个秒杀请求如果100ms以内得到令牌,就算是秒杀成功,否则就返回秒杀失败
                if (limiter.tryAcquire(100, TimeUnit.MILLISECONDS)) {
                    System.out.println("恭喜您,秒杀成功");
                } else {
                    System.out.println("秒杀失败,请继续努力");
                }
            }).start();
            //等待新的令牌生成
            Thread.sleep(10);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

booth-ZDH

爪哇一生

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值