限流,单机,分布式限流

总结:解决网站的高访问量,有三大利器,缓存,降级,限流,我这里讲解一下 常用的几种限流手段。

          单机 ,有型号量,令牌通,漏桶,

          分布式,可以考虑从网关,redis ngnix, 阿里 Sentinel 等手段解决 。话不多说代码如下:

      1.单机:

        1.1 型号量

    // 线程池

ExecutorService exec = Executors.newCachedThreadPool();
// 只能5个线程同时访问
final Semaphore semp = new Semaphore(5);

@Override
public void limit() {
// 模拟20个客户端访问
for (int index = 0; index < 20; index++) {
final int NO = index;
Runnable run = new Runnable() {
public void run() {
try {
// 获取许可 一直阻塞
semp.acquire();
// semp.tryAcquire(1, TimeUnit.MINUTES); //这个尝试 多长时间获取 到
//处理业务
log.info("Accessing: " + NO);
Thread.sleep((long) (Math.random() * 10000));
log.info("存在多少有效" + semp.availablePermits());
} catch (InterruptedException e) {
log.info("error:{}",e);
} finally {
// 访问完后,释放
semp.release();
}
}
};
exec.execute(run);
}
// 退出线程池
//exec.shutdown();
}


1.2 guava
ExecutorService exec = Executors.newCachedThreadPool();// 线程池
final RateLimiter limit = RateLimiter.create(2);//1s只能有10个

@Override
public void limit() {
// 模拟20个客户端访问
for (int index = 0; index < 20; index++) {
final int NO = index;
Runnable run = new Runnable() {
public void run() {
try {
// 获取许可
limit.acquire();
//处理业务
log.info("Accessing: " + NO);
Thread.sleep((long) (Math.random() * 10000));
} catch (InterruptedException e) {
log.info("error:{}", e);
}
}
};
exec.submit(run);
}
}

2.0 分布式版本
  2.1  redis-spring-data
@Autowired
private RedisTemplate redisTemplate;
ExecutorService exec = Executors.newCachedThreadPool();// 线程池
@Override
public void limit() {
//这里我用 包名+类名+方法
String key = "com.example.demo.limit.redis.ResdisLimitServiceImpl.limit";

RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
for (int i = 0; i < 100; i++) {
final int no = i;
exec.submit(new Runnable() {
@Override
public void run() {
if (counter.incrementAndGet() > 10) {
//拒绝请求
log.info("拒绝请求{}", no);
}
try {
//处理请求
log.info("处理请求{}", no);
} finally {
counter.decrementAndGet();
}
try {
Thread.sleep((long) (Math.random() * 10000));
} catch (InterruptedException e) {

}
}
});
}
}
2.2 redission 版本

@Autowired
private RedissonClient redisson;

ExecutorService exec = Executors.newCachedThreadPool();// 线程池

@Override
public void limit() {
RSemaphore semaphore = redisson.getSemaphore("semaphore");
semaphore.trySetPermits(10);
log.info("有效:{}",semaphore.availablePermits());
for (int i = 0; i <100 ; i++) {
final int no = i;
exec.submit(new Runnable() {
@Override
public void run() {
try {
if(semaphore.tryAcquire(1, TimeUnit.SECONDS)){
try {
log.info("处理业务{}",no);
Thread.sleep((long) (Math.random() * 10000));
}finally {
semaphore.release(1);
}
}else {
log.info("拒绝业务{}",no);
}
} catch (InterruptedException e) {
log.error("error:{}",e);
}
}
});
}
}

3.0 基于注解 redis开发 限流 使用方便

使用如下:

@Limit(key = "test", period = 100, count = 10)
@PostMapping("dept/update")
public ResponseResult updateDept(String name, Boolean leader, Integer id
, Double age, BigDecimal price, ResponseResultCode em){

return ResponseResultFactory.success("添加成功");
}
jmeter 测试如下 具体实现 参考我的代码库




转载于:https://www.cnblogs.com/lyc88/articles/11004120.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值