限流的一般思路:
1、随机丢弃一定规则的用户(迅速过滤掉90%的用户);
2、MQ削峰(比如设一个MQ可以容纳的最大消息量,达到这个量后MQ给予reject);
3、业务逻辑层使用RateLimiter进行限流;
4、最终可以承受的流量到达DB层。
package ratelimiter; import com.google.common.util.concurrent.RateLimiter; import org.springframework.stereotype.Component; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** * @author xfyou * @date 2018/10/31 */ @Component public class AccessLimitService { private static volatile int acquireCount = 0; private static final Object OBJECT = new Object(); /** * 每秒可以获得50个许可证 */ private RateLimiter rateLimiter = RateLimiter.create(50); private boolean tryAcquire() { // 等待1秒钟如果未能获取到许可证就返回false,否则返回true return rateLimiter.tryAcquire(1, 1000, TimeUnit.MILLISECONDS); } public static void main(String[] args) { AccessLimitService accessLimitService = new AccessLimitService(); ExecutorService executorService = Executors.newCachedThreadPool(); for (int i = 0; i < 1000; i++) { executorService.execute(new Runnable() { @Override public void run() { if (accessLimitService.tryAcquire()) { System.out.println("获取许可证,执行业务逻辑。"); synchronized (OBJECT) { System.out.println(++acquireCount); } try { Thread.sleep(20); } catch (InterruptedException ex) { // } } else { System.err.println("未获取到许可证,请求可以丢弃。"); } } }); try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } executorService.shutdown(); } }
原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/15893.html