高并发系统处理之——限流
对于高并发应用服务,有三个很好的方案可以保护系统
1.缓存 缓存的目的是提升系统访问速度和增大系统处理容量
2.降级 降级是当服务出现问题或者影响到核心流程时,需要暂时屏蔽掉,待高峰或者问题解决后再打开
3.限流 限流的目的是通过对并发访问/请求进行限速,或者对一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务、排队或等待、降级等处理
限流算法
常用的限流算法有两种:漏桶算法和令牌桶算法
漏桶算法
漏桶算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出,可以看出漏桶算法能强行限制数据的传输速率。
对于很多应用场景来说,除了要求能够限制数据的平均传输速率外,还要求允许某种程度的突发传输。这时候漏桶算法可能就不合适了,令牌桶算法更为适合。
令牌桶算法
令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。
在google开源的guava工具包中有一个类RateLimiter实现了这个功能,使用比较简单,使用的是令牌桶算法:
//创建一个1s只能有0.5个请求的限流器(括号里的参数是1s内的请求数)
RateLimiter rateLimiter = RateLimiter.create(0.5);
Arrays.asList("123", "456", "789", "1123", "11234").forEach(a -> {
//获取令牌
rateLimiter.acquire();
System.out.println(a + "------" + System.currentTimeMillis());
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
打印输出:
123------1534918207667
456------1534918209625
789------1534918211624
1123------1534918213625
11234------1534918215625
- 1
- 2
- 3
- 4
- 5
- 6
后续再看看源码。
题外话
除此之外,Java里有个类Semaphore,信号量,可以使得一段代码同时被多个线程并发处理。(加sychronized是只有一个线程)
//创建,参数为可并发数量
Semaphore semaphore = new Semaphore(2);
//获取锁
semaphore.acquire();
//释放锁
semaphore.release();
原文地址https://blog.csdn.net/doujinlong1/article/details/81943327