2023年2月7日 作者 zeroheart

单机限流的几种方式

(34条消息) 单机限流的几种方式_阳光甚好的博客-CSDN博客

(34条消息) 单机/分布式限流-漏桶/令牌桶/滑动窗口/redis/nginx/sentinel_单机版限流_让火车在天上飞的博客-CSDN博客

/**

  • 原子计数限流方式
  • 简单粗暴的限流方式,没有平滑处理,需要根据场景使用
    */
    public class AtomicLimit {
    private AtomicInteger requestCount=new AtomicInteger(0); public void doRequest(String threadName){
    try {
    if (requestCount.incrementAndGet() > 10) {
    System.out.println(threadName + “请求过多请稍后重试”);
    } else {
    System.out.println(threadName + “您的请求已经处理”);
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    //mark 正常业务逻辑处理结束
    }
    }finally {
    requestCount.decrementAndGet();
    }
    }

/**

  • 利用信号量方式限流
    */
    public class ExcutorSignal {
    public static void main(String[] args) {
    ExecutorService exec = Executors.newFixedThreadPool(20);
    //只能5个线程同时访问
    final Semaphore semp = new Semaphore(5);
    for (int i = 0; i < 20; i++) {
    final int taskNo = i;
    Runnable run = new Runnable() {
    @Override
    public void run() {
    try {
    semp.acquire();//获取许可
    String name = Thread.currentThread().getName();
    System.out.println(“开始” + name + “_” + taskNo);
    Thread.sleep((long) (Math.random() * 10000));
    semp.release();//访问完后释放
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    };
    exec.execute(run);
    }
    }
    }

/**

  • 令牌桶,主要限制流入
  • 限流,多的请求直接拒绝
  • 可以针对方法级别配置
    */
    public class TrafficShapper {
    private RateLimiter rateLimiter = RateLimiter.create(10);
    public void doRequest(String threadName) {
    boolean isAcquired = rateLimiter.tryAcquire(1, 3000L, TimeUnit.MICROSECONDS);//rateLimiter.tryAcquire();
    if (isAcquired) {
    System.out.println(threadName + “:调用成功”);
    } else {
    System.out.println(threadName + “:当前调用人数过多,请稍后重试”);
    }
    } public static void main(String[] args) {
    final TrafficShapper shapper = new TrafficShapper();
    final CountDownLatch latch = new CountDownLatch(1);
    final Random random = new Random(10);
    for (int i = 0; i < 20; i++) {
    final int finalT = i;
    Thread t = new Thread(new Runnable() {
    @Override
    public void run() {
    try {
    latch.await();
    int sleepTime = random.nextInt(1000);
    Thread.sleep(sleepTime);
    shapper.doRequest(“t-” + finalT);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    });
    t.start();
    }
    latch.countDown();
    }

}

CountDownLatch latch=new CountDownLatch(1);//mark 保证线程同一时刻启动
latch.await();
latch.countDown();//当前计数为0则不执行操作,当计数从>0变成0后,所有线程同时启动