上篇學習了zuul路由,這邊繼續學習,粗糙的記錄zuul過濾器的用法java
如今對請求url作個約定,在請求url上沒有帶參數key=123的url所有過濾掉redis
①localhost:7000/product/list?key=1234 ---不過濾算法
②localhost:7000/product/list ---過濾,不執行spring
完成以上功能,在gateway服務中,代碼以下 : docker
package com.cloud.gateway.filters; 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 org.springframework.util.StringUtils; import javax.servlet.http.HttpServletRequest; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; /** * 常量類 * 過濾器狀態 FilterConstants * 請求狀態 HttpStatus * 引用其中的屬性值便可,無需本身寫 */ @Component public class PreFilter extends ZuulFilter { /** * filter類型 * @return */ @Override public String filterType() { return PRE_TYPE; } /** * filter執行順序,值越小優先級越高 * 官方推薦使用x-1方式優先排序 * @return */ @Override public int filterOrder() { return PRE_DECORATION_FILTER_ORDER - 1; } /** * filter 開啓關閉 * @return */ @Override public boolean shouldFilter() { return true; } /** * 實現filter邏輯 * @return * @throws ZuulException */ @Override public Object run() throws ZuulException { RequestContext requestContext = RequestContext.getCurrentContext(); HttpServletRequest request =requestContext.getRequest(); String key=request.getParameter("key"); //若是不存在,則設置沒有權限不經過,狀態爲401 if (StringUtils.isEmpty(key)){ requestContext.setSendZuulResponse(false); requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value()); } return null; } }
瀏覽器訪問成功則返回list列表,失敗則返回錯誤頁面,錯誤碼:401瀏覽器
再來實現一個post過濾器,在獲得結果以後,實如今post filter階段,返回response的,給header頭部加點信息,代碼以下: dom
package com.cloud.gateway.filters; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletResponse; import java.util.UUID; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_RESPONSE_FILTER_ORDER; /** * 常量類 * 過濾器狀態 FilterConstants * 請求狀態 HttpStatus * 引用其中的屬性值便可,無需本身寫 */ @Component public class PostFilter extends ZuulFilter { /** * filter類型 * * @return */ @Override public String filterType() { return POST_TYPE; } /** * filter執行順序,值越小優先級越高 * 官方推薦使用x-1方式優先排序 * * @return */ @Override public int filterOrder() { return SEND_RESPONSE_FILTER_ORDER - 1; } /** * filter 開啓關閉 * * @return */ @Override public boolean shouldFilter() { return true; } /** * 實現filter邏輯 * * @return * @throws ZuulException */ @Override public Object run() throws ZuulException { RequestContext requestContext = RequestContext.getCurrentContext(); HttpServletResponse response = requestContext.getResponse(); response.setHeader("POST-UUID", UUID.randomUUID().toString()); return null; } }
瀏覽器控制檯 請求信息 : ide
寫了兩次, 套路也都摸清了,能寫的地方也就這麼幾個點,後面再作 限流 操做,結合上面學的,限流作在請求filter最靠前的地方,比鑑權pre前執行,否則流量都進去了,這裏須要一個算法---令牌桶算法,這個算法不少地方已經實現了,拿來用便可,意思是以必定速率將令牌放入桶中,桶中的令牌滿了,就不會再放進去了,外部的請求進入,請求將得到桶中的令牌,得令牌者可通行,沒有令牌請求將被拒絕post
下面代碼實現 : 學習
package com.cloud.gateway.filters; import com.cloud.gateway.exceptions.RateLimiterException; import com.google.common.util.concurrent.RateLimiter; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.exception.ZuulException; 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 RateLimiterFilter extends ZuulFilter { //create 每秒放入100個令牌 private static final RateLimiter RATE_LIMITER = RateLimiter.create(100); /** * filter類型 * * @return */ @Override public String filterType() { return PRE_TYPE; } /** * filter執行順序,值越小優先級越高 * 官方推薦使用x-1方式優先排序 * 選擇最高優先級SERVLET_DETECTION_FILTER_ORDER,並-1 * * @return */ @Override public int filterOrder() { return SERVLET_DETECTION_FILTER_ORDER - 1; } /** * filter 開啓關閉 * * @return */ @Override public boolean shouldFilter() { return true; } /** * 實現filter邏輯 * * @return * @throws ZuulException */ @Override public Object run() throws ZuulException { //判斷--獲取通行令牌-->若是沒有令牌不等於以前的沒有權限401,能夠拋出自定義異常或者其餘處理 if (!RATE_LIMITER.tryAcquire()) { throw new RateLimiterException(); } return null; } }
自定義異常:
package com.cloud.gateway.exceptions; public class RateLimiterException extends RuntimeException { }
以上是過濾器的簡單示例
還有一個Zuul關於鑑權的使用,涉及新建user服務,也會用到docker、redis,剛剛入手mac,上面什麼都沒有,裝好了再繼續下面的學習實踐
---------------------------------------------------------