秒杀下单接口限流
因为秒杀的特殊业务场景,生产场景下,还有可能要对秒杀下单接口进行访问流量控制,防止过多的请求进入到后端服务器。对于限流的实现方式,我们之前已经接触过通过nginx限流,网关限流。但是他们都是对一个大的服务进行访问限流,如果现在只是要对某一个服务中的接口方法进行限流呢?这里推荐使用google提供的guava工具包中的RateLimiter进行实现,其内部是基于令牌桶算法进行限流计算
1)添加依赖
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>28.0-jre</version> </dependency>
2)自定义限流注解
@Inherited @Documented @Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface AccessLimit {}
3)自定义切面类
@Component @Scope @Aspect public class AccessLimitAop { @Autowired private HttpServletResponse httpServletResponse; private RateLimiter rateLimiter = RateLimiter.create(20.0); @Pointcut("@annotation(com.changgou.webSecKill.aspect.AccessLimit)") public void limit(){} @Around("limit()") public Object around(ProceedingJoinPoint proceedingJoinPoint){ boolean flag = rateLimiter.tryAcquire(); Object obj = null; try{ if (flag){ obj=proceedingJoinPoint.proceed(); }else{ String errorMessage = JSON.toJSONString(new Result(false,StatusCode.ERROR,"fail")); outMessage(httpServletResponse,errorMessage); } }catch (Throwable throwable) { throwable.printStackTrace(); } return obj; } private void outMessage(HttpServletResponse response, String errorMessage) { ServletOutputStream outputStream = null; try { response.setContentType("application/json;charset=UTF-8"); outputStream = response.getOutputStream(); outputStream.write(errorMessage.getBytes("UTF-8")); } catch (IOException e) { e.printStackTrace(); }finally { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } }
4)使用自定义限流注解