java app接口代码下载_Java生鲜电商平台-接口限流的技术分析与源代码下载(小程序/APP)...

Java生鲜电商平台-接口限流的技术分析与源代码下载(小程序/APP)

说明:在实际的Java生鲜电商平台中,在对外暴露的接口中存在某些人为或者攻击者的恶意调用与攻击,这个时候为了系统的安全,就需要对某些接口进行限流操作,网上的大部分的接

口限流都是基于guava或者阿里巴巴的Sentinel,本文只是根据实际的业务出发,采用自定义注解来进行方法限流,满足我们的日常业务的要求。

1。阅读本文你需要掌握的知识为:

如何限流。如何基于注解限流,相关源代码等

2.  首先我们看下POM文件.  基于SpringBoot2.2.2 这个版本

4.0.0

org.springframework.boot

spring-boot-starter-parent

2.2.2.RELEASE

com.ctg.test

springboot-limit-api

0.0.1-SNAPSHOT

springboot-limit-api

springboot-limit-api

1.8

org.springframework.boot

spring-boot-starter-web

org.aspectj

aspectjweaver

org.springframework.boot

spring-boot-starter-test

test

com.google.guava

guava

22.0

com.alibaba

fastjson

1.2.47

org.springframework.boot

spring-boot-maven-plugin

2. 限流的注解:可以根据自己的业务,灵活设置默认的值

import java.lang.annotation.*;

@Inherited

@Documented

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE,ElementType.PACKAGE})

@Retention(RetentionPolicy.RUNTIME)public @interfaceRateLimit {double limitNum() default 20; //默认每秒放入桶中的token

}

3. 基于sping的AOP进行业务限流

importcom.fasterxml.jackson.annotation.JsonInclude;importcom.fasterxml.jackson.databind.ObjectMapper;importcom.google.common.util.concurrent.RateLimiter;importorg.aspectj.lang.ProceedingJoinPoint;importorg.aspectj.lang.Signature;importorg.aspectj.lang.annotation.Around;importorg.aspectj.lang.annotation.Aspect;importorg.aspectj.lang.annotation.Pointcut;importorg.aspectj.lang.reflect.MethodSignature;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.context.annotation.Scope;importorg.springframework.stereotype.Component;importjavax.servlet.ServletOutputStream;importjavax.servlet.http.HttpServletResponse;importjava.io.IOException;importjava.lang.reflect.Method;importjava.util.concurrent.ConcurrentHashMap;

@Component

@Scope

@Aspectpublic classRateLimitAspect {private Logger log = LoggerFactory.getLogger(this.getClass());//用来存放不同接口的RateLimiter(key为接口名称,value为RateLimiter)

private ConcurrentHashMap map = new ConcurrentHashMap<>();private static ObjectMapper objectMapper = newObjectMapper();privateRateLimiter rateLimiter;

@AutowiredprivateHttpServletResponse response;

@Pointcut("@annotation(com.ctg.test.limit.RateLimit)")public voidserviceLimit() {

}

@Around("serviceLimit()")public Object around(ProceedingJoinPoint joinPoint) throwsNoSuchMethodException {

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);double limitNum = annotation.limitNum(); //获取注解每秒加入桶中的token

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{//拒绝了请求(服务降级)

String result = objectMapper.writeValueAsString(ResultUtil.error(201, "你操作太过频繁,请稍后再试!"));

log.info("拒绝了请求:" +result);

outErrorResult(result);

}

}catch(Throwable throwable) {

throwable.printStackTrace();

}returnobj;

}//将结果返回

public voidoutErrorResult(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);

}

}

4. 基础的业务类与返回实现. 包括基础的代码与工具类

/*** @Description: 统一接口返回值*/

public class Result{/**错误码.*/

privateInteger code;/**提示信息.*/

privateString msg;/**具体的内容.*/

privateT data;publicInteger getCode() {returncode;

}public voidsetCode(Integer code) {this.code =code;

}publicString getMsg() {returnmsg;

}public voidsetMsg(String msg) {this.msg =msg;

}publicT getData() {returndata;

}public voidsetData(T data) {this.data =data;

}

}

public classResultCode {public static final Integer SUCCESS = 200;public static final Integer ERROR = 201;public static final Integer UNKNOWERROR = 202;

}

public classResultUtil {public staticResult success() {return success(null);

}public staticResult success(Object object) {

Result result= newResult();

result.setCode(ResultCode.SUCCESS);

result.setMsg("成功");

result.setData(object);returnresult;

}public staticResult success(Integer code,Object object) {

Result result= newResult();

result.setCode(code);

result.setMsg("成功");

result.setData(object);returnresult;

}public staticResult error( String msg) {

Result result= newResult();

result.setCode(ResultCode.ERROR);

result.setMsg(msg);returnresult;

}public staticResult error(Integer code, String msg) {

Result result= newResult();

result.setCode(code);

result.setMsg(msg);

result.setData("");returnresult;

}

}

5. 进行业务代码测试

importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.ResponseBody;importjava.util.HashMap;importjava.util.Map;/*** @Description:

*http://localhost:8080/test1

*http://localhost:8080/test2*/@Controllerpublic classTestController {

@RateLimit(limitNum= 1.0)

@RequestMapping("/test1")

@ResponseBodypublicObject getResults() {return ResultUtil.success(200,"test1");

}

@RateLimit(limitNum= 10.0)

@RequestMapping("/test2")

@ResponseBodypublicObject getResultTwo(){

Mapmap =new HashMap<>();return ResultUtil.success(200,"test2");

}

}

最终的结果为:

4ead2c71d77d1903a4af8a50c85bb81a.png

结语

复盘与总结.

总结:

做Java生鲜电商平台的互联网应用,无论是生鲜小程序还是APP,在高可用的系统设计中限流设计思路是非常重要的,本文只是起一个抛砖引玉的作用,

希望用生鲜小程序的搭建限流的设计思路实战经验告诉大家一些实际的项目经验,希望对大家有用.

QQ:137071249

共同学习QQ群:793305035

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值