令牌桶 限流流程图:
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":"请求超限"}