Spring Cloud詳細講解zuul集成Eureka流程
zuul集成Eureka
通過剛才的示例,我們已經可以簡單地使用 Zuul 進行路由的轉發瞭,在實際使用中我們通常是用 Zuul 來代理請求轉發到內部的服務上去,統一為外部提供服務。內部服務的數量會很多,而且可以隨時擴展,我們不可能每增加一個服務就改一次路由的配置,所以也得通過結合 Eureka 來實現動態的路由轉發功能。首先需要添加 Eureka 的依賴,代碼如下所示。
<dependency> <groupId>org.springframework.cloud</groupId > <artifactId>spring-cloud- starter-netflix-eureka-client</artifactId> <version>2.2.9.RELEASE</version> </dependency>
說明:這裡的eureka-client版本要使用2.2.9.RELEASE,否則會報錯!
啟動類不需要修改,因為 @EnableZuulProxy 已經自帶瞭 @EnableDiscoveryClient。隻需要在配置文件中增加Eureka 的地址即可:
eureka:
client:
service-url:
defaultZone: http://admin:1357@localhost:8761/eureka
重啟服務,我們可以通過默認的轉發規則來訪問 Eureka中的服務。訪問規則是“網關服務地址+訪問的服務名稱+接口 URI”。
如上面的訪問改為: http://localhost:7000/ws-user-server/user/23
Zuul路由配置
當 Zuul 集成 Eureka 之後,其實就可以為 Eureka 中所有的服務進行路由操作瞭,默認的轉發規則就是“網關 服務地址+訪問的服務名稱+接口 URI”。在給服務指定名稱的時候,應盡量短一點,這樣的話我們就可以用默認的路由規則進行請求,不需要為每個服務都定一個路由規則,這樣就算新增瞭服務,API 網關也不用修改和重啟瞭。
1. 指定具體服務路由
我們可以為每一個服務都配置一個路由轉發規則:
zuul:
routes: #路由轉發
ws-user-server:
path: /api-user/**
上述代碼將ws-user-server 服務的路由地址配置成瞭api-user,也就是當需要訪問 ws-user-server中的接口時,我們可以通過 api-user/user/20 來進行。這其實就是將服務名稱變成瞭我們自定義的名稱。註意: /api-user/** 後面一定要配置兩個星號,兩個星號表示可以轉發任意層級的 URL,比如“/apiuser/user/1”。如果隻配置一個星號,那麼就隻能轉發一級,比如“/api-user/user”。默認的路由規則還適用!!!!
2. 路由前綴
有的時候我們會想在 API 前面配置一個統一的前綴,就可
以通過 Zuul 中的配置來實現:
zuul:
prefix: /v1
上述訪問地址變為: http://localhost:7000/v1/api-user/user/20
Zuul過濾器
過濾器類型
Zuul 中的過濾器跟我們之前使用的 javax.servlet.Filter不一樣,javax.servlet.Filter 隻有一種類型,可以通過配置 urlPatterns 來攔截對應的請求。
而 Zuul 中的過濾器總共有 4 種類型,且每種類型都有對應的使用場景。
1)pre
可以在請求被路由之前調用。適用於身份認證的場景,認證通過後再繼續執行下面的流程。
2)route
在路由請求時被調用。適用於灰度發佈場景,在將要路由的時候可以做一些自定義的邏輯。
3)post
在 route 和 error 過濾器之後被調用。這種過濾器將請求路由到達具體的服務之後執行。適用於需要添加響應頭,記錄響應日志等應用場景。
4)error
處理請求時發生錯誤時被調用。在執行過程中發送錯誤時會進入 error 過濾器,可以用來統一記錄錯誤信息。
請求生命周期
過濾器執行的順序,請求發過來首先到 pre 過濾器,再到 routing 過濾器,最後到 post 過濾器,任何一個過濾器有異常都會進入 error 過濾器。通過 com.netflix.zuul.http.ZuulServlet 也可以看出完整執行順序,ZuulServlet 類似 Spring-MVC 的DispatcherServlet,所有的 Request 都要經過ZuulServlet 的處理。
ZuulServlet 的service實現:
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { try { this.init((HttpServletRequest)servletReque st(HttpServletResponse)servletResponse); RequestContext context = RequestContext.getCurrentContext(); context.setZuulEngineRan(); try {this.preRoute(); } catch (ZuulException var13) { this.error(var13); this.postRoute(); return; }try {this.route(); } catch (ZuulException var12) { this.error(var12); this.postRoute(); return; }try {this.postRoute();} catch (ZuulException var11) { this.error(var11); } } catch (Throwable var14) { this.error(new ZuulException(var14, 500, "UNHANDLED_EXCEPTION_" + var14.getClass().getName())); } finally { RequestContext.getCurrentContext().unset() ; } }
使用過濾器
創建一個token驗證的過濾器,繼承抽象類ZuulFilter,
如下:
import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; public class TokenFilter extends ZuulFilter { /*** 過濾器類型,可選值有 pre、route、post、 error。* @return */ @Override public String filterType() { return "pre"; } /*** 過濾器的執行順序,數值越小,優先級越高。 * @return */ @Override public int filterOrder() { return 0; } /*** 是否執行該過濾器,true 為執行,false 為不 執行,這個也可以利用配置中心來實現,達到動態的開啟和 關閉過濾器。 * @return */ @Override public boolean shouldFilter() { return true; }/*** 執行自己的業務邏輯,判斷是否 * @return * @throws ZuulException */ @Override public Object run() throws ZuulException { RequestContext requestContext=RequestContext.getCurrentCo ntext();String token= requestContext.getRequest().getHeader("tok en"); //如果token沒傳或 失效 if(null==token){ requestContext.setSendZuulResponse(false); //告訴 Zuul 不需要將當前請求轉發到後端的服務瞭 requestContext.setResponseBody(" {code:0,msg:'返回給客戶端的數據'}"); requestContext.getResponse().setContentTyp e("application/json; charset=utf-8"); }return null; } }
使過濾器生效:
@Configuration public class FilterConfig { @Bean public TokenFilter tokenFilter(){ return new TokenFilter(); } }
到此這篇關於Spring Cloud詳細講解zuul集成Eureka流程的文章就介紹到這瞭,更多相關Spring Cloud Eureka內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- SpringCloud超詳細講解微服務網關Zuul
- Zuul 如何屏蔽服務和指定路徑
- Spring Cloud Zuul自定義過濾器的實現
- springCloud項目搭建流程步驟分解
- PHP中token的生成案例