springcloud常用組件
1、服務註冊與發現:Eureka
2、服務網關: Zuul
3、服務負載均衡:Ribbon
4、服務之間調用:Feign
5、服務熔斷:Hystrix ---因官網不繼續維護,可以使用阿里提供的Alibaba Sentinel 輕量級的流量控制、熔斷降級 Java 庫
6、配置中心:config ---如果不想自己維護,可以使用阿里雲nacos作爲配置中心
2、zuul路由網管
主要權限驗證和限流,
(1)、權限驗證:這裏具體用ZuulFilter實現
方法說明
filterType : filter類型,分爲pre、error、post、 route
filterOrder: filter執行順序,通過數字指定,數字越小,執行順序越先
shouldFilter: filter是否需要執行 true執行 false 不執行
run : filter具體邏輯(上面爲true那麼這裏就是具體執行邏輯)
filter類型說明
pre: 請求執行之前filter
route: 處理請求,進行路由
post: 請求處理完成後執行的filter
error: 出現錯誤時執行的filter
/**
* 登錄過濾器
*記得類上加Component註解
*/
@Component
public class LoginFilter extends ZuulFilter {
/**
* 過濾器類型,前置過濾器
*/
@Override
public String filterType() {
return PRE_TYPE;
}
/**
* 過濾器順序,越小越先執行
*/
@Override
public int filterOrder() {
return 4;
}
/**
* 過濾器是否生效
* 返回true代表需要權限校驗,false代表不需要用戶校驗即可訪問
*/
@Override
public boolean shouldFilter() {
//共享RequestContext,上下文對象
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
System.out.println(request.getRequestURI());
//需要權限校驗URL
if ("/apigateway/order/api/v1/order/save".equalsIgnoreCase(request.getRequestURI())) {
return true;
} else if ("/apigateway/order/api/v1/order/list".equalsIgnoreCase(request.getRequestURI())) {
return true;
} else if ("/apigateway/order/api/v1/order/find".equalsIgnoreCase(request.getRequestURI())) {
return true;
}
return false;
}
/**
* 業務邏輯
* 只有上面返回true的時候,纔會進入到該方法
*/
@Override
public Object run() throws ZuulException {
//JWT
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
//token對象,有可能在請求頭傳遞過來,也有可能是通過參數傳過來,實際開發一般都是請求頭方式
String token = request.getHeader("token");
if (StringUtils.isBlank((token))) {
token = request.getParameter("token");
}
System.out.println("頁面傳來的token值爲:" + token);
//登錄校驗邏輯 如果token爲null,則直接返回客戶端,而不進行下一步接口調用
if (StringUtils.isBlank(token)) {
// 過濾該請求,不對其進行路由
requestContext.setSendZuulResponse(false);
//返回錯誤代碼
requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
}
return null;
}
}
具體操作用如下代碼
原文章地址:https://www.cnblogs.com/qdhxhz/p/9601170.html
(2)、限流:這裏採用ZuulFilter + RateLimiter(基於guava框架來做網關限流),RateLimiter是令牌桶算法
/**
* 訂單限流
*其它和上面都一樣,只是run()中邏輯不一樣
*/
@Component
public class OrderRateLimiterFilter extends ZuulFilter {
//每秒產生1000個令牌
private static final RateLimiter RATE_LIMITER = RateLimiter.create(1000);
@Override
public String filterType() {
return PRE_TYPE;
}
@Override
public int filterOrder() {
return -4;
}
@Override
public boolean shouldFilter() {
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
//只對訂單接口限流
if ("/apigateway/order/api/v1/order/save".equalsIgnoreCase(request.getRequestURI())) {
return true;
}
return false;
}
@Override
public Object run() throws ZuulException {
RequestContext requestContext = RequestContext.getCurrentContext();
//就相當於每調用一次tryAcquire()方法,令牌數量減1,當1000個用完後,那麼後面進來的用戶無法訪問上面接口
//當然這裏只寫類上面一個接口,可以這麼寫,實際可以在這裏要加一層接口判斷。
if (!RATE_LIMITER.tryAcquire()) {
requestContext.setSendZuulResponse(false);
//HttpStatus.TOO_MANY_REQUESTS.value()裏面有靜態代碼常量
requestContext.setResponseStatusCode(HttpStatus.TOO_MANY_REQUESTS.value());
}
return null;
}
}
文章來源:https://www.cnblogs.com/qdhxhz/p/9601170.html
下一篇文章介紹漏桶算法和令牌桶算法區別