Guava之RateLimiter如何限流

前言

流量控制是老生常谈的话题,包括两方面:

  1. 对本系统的保护。位于业务系统的最前面;
  2. 对外部调用的并发控制。处于系统的底层;

大部分系统聊的都是前者,今天我们聊聊后者。

背景

请求外部服务,或者做批量数据同步,下游依赖服务有最大并发控制,不想接口因为限流而失败,同时又想尽可能的提高并发,怎么控制?

实战

Guava 的 RateLimiter 实现了这个功能,使用方式如下:


	private static final ThreadPoolExecutor tx = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS,
		new LinkedBlockingDeque<>(10),
		new NamedThreadFactory("yuan-cus", false),
		new ThreadPoolExecutor.CallerRunsPolicy());


	public static void main(String[] args) {
		test(30);
	}

	public static void test(int permitsPerSecond) {
		RateLimiter limiter = RateLimiter.create(permitsPerSecond);

		//记录上一次执行时间
		final long[] prev = {System.nanoTime()};
		//测试执行20次
		for (Long i = 0L; i < 100; i++) {

			//提交任务异步执行
			Long finalI = i;
			dot("submit No." + i);
			tx.execute(() -> {
				double acquire = limiter.acquire();
				dot("limiter sleep " + acquire * 1000);
				long cur = System.nanoTime();
				long interval = (cur - prev[0]) / 1000_000;
				//打印时间间隔:毫秒
				dot("Run No. " + finalI + " interval==> " + interval);
				prev[0] = cur;

			});
		}

		tx.shutdown();
	}

	private static void dot(String s) {
		long millis = System.currentTimeMillis();
		String name = Thread.currentThread().getName();
		int size = tx.getQueue().size();
		int activeCount = tx.getActiveCount();
		System.out.println("Mills:" + millis + "  Thread:" + name + " QueueSize:" + size + "activeCt:" + activeCount + " ==> " + s);
	}

特点

那么RateLimiter有哪些特点呢?
我以为主要有以下几点:

  1. 单机
  2. 基于内存
  3. 均匀的时间窗口
  4. 可以动态调整
limiter.setRate(30.0);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值