问题产生,当调用一个接口很频繁的时候,比如每秒调用一个接口100次。业务提现在抢购等。这时我们的服务器处理不过来就会拒绝服务,宕机等等。。。显然这不是我们需要的。

因此产生了限流这个。限流是什么呢,就是我只是接收那么多,多的就是等待,排队,或者拒绝,然你等待,不进入服务。。。

直接上代码:

@Inherited
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimit {
/**
* 默认每秒支持100个
* @return
*/
int limintNum() default 100;
}
/**
* 限流 切面枚举实现
*
* @author mingge
*
*/
@Component
@Scope
@Aspect
@Slf4j
public class RateLimitAspect { /**
* //用来存放不同接口的RateLimiter(key为接口名称,value为RateLimiter)
*/
private ConcurrentHashMap<String, RateLimiter> map = new ConcurrentHashMap<>(); private static final String POINT = "execution (* com.mingge..*.controller..*.*(..))"; private static ObjectMapper objectMapper = new ObjectMapper(); private RateLimiter rateLimiter; @Autowired
private HttpServletResponse response; @Pointcut(POINT)
public void serviceLimit() {
} @Around("serviceLimit()")
public Object around(ProceedingJoinPoint joinPoint) throws NoSuchMethodException {
Object obj = null;
//获取拦截的方法名
Signature sig = joinPoint.getSignature();
//获取拦截的方法名
MethodSignature msig = (MethodSignature) sig;
//返回被织入增加处理目标对象
Object target = joinPoint.getTarget();
//为了获取注解信息
Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
//获取注解信息
RateLimit annotation = currentMethod.getAnnotation(RateLimit.class);
//获取注解每秒加入桶中的token
int limitNum = annotation.limintNum();
// 注解所在方法名区分不同的限流策略
String functionName = msig.getName(); //获取rateLimiter
if(map.containsKey(functionName)){
rateLimiter = map.get(functionName);
}else {
map.put(functionName, RateLimiter.create(limitNum));
rateLimiter = map.get(functionName);
}
try {
if (rateLimiter.tryAcquire()) {
//执行方法
obj = joinPoint.proceed();
} else {
BaseVO vo=new BaseVO();
vo.setCode(100001);
vo.setMessage("系统繁忙,请稍后再试!");
//拒绝了请求(服务降级)
String result = objectMapper.writeValueAsString(vo);
log.info("拒绝了请求:" + result);
outErrorResult(result);
}
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return obj;
}
//将结果返回
public void outErrorResult(String result) {
response.setContentType("application/json;charset=UTF-8");
try (ServletOutputStream outputStream = response.getOutputStream()) {
outputStream.write(result.getBytes("utf-8"));
} catch (IOException e) {
e.printStackTrace();
}
} static {
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
} }

使用方法就是在你控制器上面加上你注解即可:

@RateLimit(limintNum = 10)

这样就起到了限流作用...这对于每秒请求频繁,并发量大的接口有好处。。。毋庸置疑佬。。。

java实现限流的更多相关文章

  1. Java限流策略

    概要 在大数据量高并发访问时,经常会出现服务或接口面对暴涨的请求而不可用的情况,甚至引发连锁反映导致整个系统崩溃.此时你需要使用的技术手段之一就是限流,当请求达到一定的并发数或速率,就进行等待.排队. ...

  2. java 服务接口API限流 Rate Limit

    一.场景描述 很多做服务接口的人或多或少的遇到这样的场景,由于业务应用系统的负载能力有限,为了防止非预期的请求对系统压力过大而拖垮业务应用系统. 也就是面对大流量时,如何进行流量控制? 服务接口的流量 ...

  3. java高并发系列 - 第15天:JUC中的Semaphore,最简单的限流工具类,必备技能

    这是java高并发系列第15篇文章 Semaphore(信号量)为多线程协作提供了更为强大的控制方法,前面的文章中我们学了synchronized和重入锁ReentrantLock,这2种锁一次都只能 ...

  4. java限流工具类

    代码 import com.google.common.util.concurrent.RateLimiter; import java.util.concurrent.ConcurrentHashM ...

  5. Java 对IP请求进行限流.

    高并发系统下, 有三把利器 缓存 降级 限流. 缓存: 将常用数据缓存起来, 减少数据库或者磁盘IO 降级: 保护核心系统, 降低非核心业务请求响应 限流: 在某一个时间窗口内对请求进行限速, 保护系 ...

  6. Java分布式IP限流和防止恶意IP攻击方案

    前言 限流是分布式系统设计中经常提到的概念,在某些要求不严格的场景下,使用Guava RateLimiter就可以满足.但是Guava RateLimiter只能应用于单进程,多进程间协同控制便无能为 ...

  7. 服务接口API限流 Rate Limit

    一.场景描述 很多做服务接口的人或多或少的遇到这样的场景,由于业务应用系统的负载能力有限,为了防止非预期的请求对系统压力过大而拖垮业务应用系统. 也就是面对大流量时,如何进行流量控制? 服务接口的流量 ...

  8. Spring Cloud Alibaba基础教程:使用Sentinel实现接口限流

    最近管点闲事浪费了不少时间,感谢网友libinwalan的留言提醒.及时纠正路线,继续跟大家一起学习Spring Cloud Alibaba. Nacos作为注册中心和配置中心的基础教程,到这里先告一 ...

  9. 超详细的Guava RateLimiter限流原理解析

    超详细的Guava RateLimiter限流原理解析  mp.weixin.qq.com 点击上方“方志朋”,选择“置顶或者星标” 你的关注意义重大! 限流是保护高并发系统的三把利器之一,另外两个是 ...

随机推荐

  1. SpringBoot整合ActiveMQ发送邮件

    虽然ActiveMQ以被其他MQ所替代,但仍有学习的意义,本文采用邮件发送的例子展示ActiveMQ 1. 生产者1.1 引入maven依赖1.2 application.yml配置1.3 创建配置类 ...

  2. round.606.div2

    A. Happy Birthday, Polycarp! 这个题意我确实没有看懂. 沃日,我懂了,我感觉我似乎都能切掉这题. B. Make Them Odd 这个我也能看懂.

  3. [CF787D] legacy

    题目 Rick和他的同事们研究出了一种新的有关放射的公式,于是许多坏人就在追赶他们.所以Rick希望在被坏人抓住之前把遗产给Morty. 在他们的宇宙里总共有n颗行星,每颗行星有它自己的编号(编号为1 ...

  4. REdis一致性方案探讨

    REdis功能强大众所周知,能够大幅简化开发和提供大并发高性能,但截止到REdis-5.0.5仍然存在如下几大问题: 一致性问题 这是由于REdis的主从复制采用的是异步复制,异常时可能发生主节点的数 ...

  5. Linux防火墙配置方法

    1)查看防火墙状态 查看防火墙状态: /etc/init.d/iptables status 暂时关闭防火墙: /etc/init.d/iptables stop 重启防火墙: /etc/init.d ...

  6. Codeforces1254B2 Send Boxes to Alice (Hard Version)(贪心)

    题意 n个数字的序列a,将i位置向j位置转移x个(a[i]-x,a[j]+x)的花费为\(x\times |i-j|\),最终状态可行的条件为所有a[i]均被K整除(K>1),求最小花费 做法 ...

  7. Gamma阶段第五次scrum meeting

    每日任务内容 队员 昨日完成任务 明日要完成的任务 张圆宁 #91 用户体验与优化https://github.com/rRetr0Git/rateMyCourse/issues/91(持续完成) # ...

  8. Django实现自动发布(2视图-服务版本查找和新增)

    前面做好了服务的管理,接下来是服务版本的管理,和服务类似,版本也有增删改查.先在服务的管理页面做一个入口,如下图: 需要在上一步的服务管理页面增加按钮.按钮方法,点击按钮跳转时要打开一个新的页面,所以 ...

  9. java项目中使用ffmpeg剪辑部分视频

    在项目中,有个需求是分享视频链接地址到微信.qq或者朋友圈,只能试看两分钟,本想着通过h5界面就能控制实现效果,代码如下,但是前端终究不是安全的,其次监听事件,如果拉播放进度条,中途停顿多次,就会出现 ...

  10. 字符串反转(java和js)

    写在前面 关于字符串反转的奇技淫巧很多, 会一种就行了, 但是解锁更多姿势可谓艺多不压身啊~~ 正文 java https://www.cnblogs.com/binye-typing/p/92609 ...