ZUUl網關-----過濾器實現登陸鑑權,高併發接口限流
(1)過濾器實現登陸鑑權
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
/**
* 登錄過濾器
*/
@Component
public class LoginFilter extends ZuulFilter {
/**
* 過濾器類型,前置過濾器 後置 訪問時 等 登陸肯定是請求接口前進行判斷 ,此處爲前置
* @return
*/
@Override
public String filterType() {
return PRE_TYPE;
}
/**
* 過濾器順序,越小越先執行
* @return
*/
@Override
public int filterOrder() {
return 4;
}
/**
* 過濾器是否生效 true 過濾器生效 執行下方run()
* @return
*/
@Override
public boolean shouldFilter() {
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
//
if ("需要登錄的路徑".equalsIgnoreCase(request.getRequestURI())){
return true;
}
return false;
}
/**
* 業務邏輯
* @return
* @throws ZuulException
*/
@Override
public Object run() throws ZuulException {
//獲取上下文對象
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
//模擬獲取token 進行判斷
String token = request.getHeader("token");
if(StringUtils.isBlank((token))){
token = request.getParameter("token");
}
//登錄校驗邏輯 根據業務場景自定義
if (StringUtils.isBlank(token)) {
requestContext.setSendZuulResponse(false);
//返回響應碼 401
requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
}
return null;
}
}
步驟總結:
1.自定義一個類 實現ZuulFilter
2.覆寫其中 四個方法 四個方法的作用,代碼中已做說明
(2)高併發下接口限流
在高併發下 進行限流 限制QPS(併發數)當併發數大於定義人數時 限流外的人員將無法訪問該接口 降低系統壓力
example: 訂單接口
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 org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
/**
* 訂單限流
*/
@Component
public class OrderRateLimiterFilter extends ZuulFilter {
//每秒產生2000個令牌 即設定每秒最好QPS爲2000人
private static final RateLimiter RATE_LIMITER = RateLimiter.create(2000);
/**
* 過濾器類型,前置過濾器 後置 訪問時 等 登陸肯定是請求接口前進行判斷 ,此處爲前置
* @return
*/
@Override
public String filterType() {
return PRE_TYPE;
}
/**
* 過濾器順序,越小越先執行
* @return 查看得知 系統設定最小爲-3,我此處設爲-4意思爲 所有過濾器 他最先執行
*/
@Override
public int filterOrder() {
return -4;
}
/**
* 過濾器是否生效 true 過濾器生效 執行下方run()
* @return
*/
@Override
public boolean shouldFilter() {
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
//只對訂單接口限流 次數Url爲自定義訂單路徑
if ("/zuuiapi/order/pay".equalsIgnoreCase(request.getRequestURI())) {
return true;
}
return false;
}
/**
* 業務邏輯
* @return
* @throws ZuulException
*/
@Override
public Object run() throws ZuulException {
RequestContext requestContext = RequestContext.getCurrentContext();
//嘗試獲取令牌 每一個用戶訪問該接口都會佔用一個令牌 如果獲取不到令牌說明已達到限流峯值 則返回數據拋出響應碼
if (!RATE_LIMITER.tryAcquire()) {
requestContext.setSendZuulResponse(false);
requestContext.setResponseStatusCode(HttpStatus.TOO_MANY_REQUESTS.value());
}
return null;
}
}
此僅僅爲訂單接口 限流 如果要限流多個 重複操作即可,,