令牌桶 限流流程图:
RateLimitFilter :
package com.wangfajun.filter;
import com.alibaba.fastjson.JSON;
import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.wangfajun.utils.Result;
import org.springframework.stereotype.Component;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVLET_DETECTION_FILTER_ORDER;
/**
* 限流
*/
@Component
public class RateLimitFilter extends ZuulFilter {
//1个令牌
private static final RateLimiter rateLimit = RateLimiter.create(1);
@Override
public String filterType() {
return PRE_TYPE;
}
@Override
public int filterOrder() {
return SERVLET_DETECTION_FILTER_ORDER-1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext requestContext = RequestContext.getCurrentContext();
if(!rateLimit.tryAcquire()){
requestContext.setSendZuulResponse(false);//不通过
requestContext.getResponse().setContentType("text/html;charset=UTF-8");
requestContext.setResponseBody(JSON.toJSONString(Result.REQUEST_LIMIT));
}
return null;
}
}
Result:
package com.wangfajun.utils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* 返回信息封装类
*/
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Result {
private int code;
private String msg;
public static Result REQUEST_LIMIT = new Result(-10001, "请求超限");
public static Result SERVER_ERROR = new Result(-10002, "服务端异常");
public static Result PARAM_ERROR = new Result(-10003, "token缺失");
}
ReturnInfo:
package com.wangfajun.utils; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; /** * 返回信息 */ @Data @ToString @NoArgsConstructor @AllArgsConstructor public class ReturnInfo<T> { private int returnCode; private String returnMsg; private T content; public ReturnInfo(T content){ this.content = content; } public ReturnInfo(Result codeMsg){ if(codeMsg!=null){ this.returnCode = codeMsg.getCode(); this.returnMsg = codeMsg.getMsg(); } } //成功 public static <T> ReturnInfo<T> success(T content){ return new ReturnInfo<T>(content); } //成功 public static <T> ReturnInfo<T> success(Result codeMsg){ return new ReturnInfo<T>(codeMsg); } //失败 public static <T> ReturnInfo<T> error(Result codeMsg){ return new ReturnInfo<T>(codeMsg); } }
pom:
<dependencies>
<!--eureka--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!--zuul--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!--fastjson--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.38</version> </dependency> </dependencies>
一秒内不停提交请求:响应信息:{"code":-10001,"msg":"请求超限"}