Zuul的常用注解及配置


Zuul 微服務網關

作用:

Zuul的核心其實就是一系列過濾器

-身份認證與安全

-審查與監控

-動態路由

-壓力測試

-負載分配

-靜態響應處理

-多區域彈性

 

加入Zuul后的軟件架構:

 

Zuul的spring依賴自帶了springweb依賴,因此建項目時只要導入Zuul依賴即可

引入eureka客戶端依賴,以拉取客戶端列表

 

在主類上加入注解:

@EnableZuulProxy //開啟Zuul的網關功能

配置文件:

 

server:
port: 10010
spring:
application:
name: zuul
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
zuul:
  routes:
  user-uservice: /user-service/**  #這是默認的路由條目,只要zuul連上eureka就會獲取eureka上的服務列表,並且根據這個服務列表提供所有服務的自動配置,而且此默認的路由一直都存在,即:不管你寫不寫,都有這條
    user-service: /user/**  #訪問地址為127.0.0.1:10010/user/user/16
  ignored-services:  #這里是不路由的服務,書寫方式是集合的方式
    - consumer-service

去除路由前綴:

 

server:
port: 10010
spring:
application:
name: zuul
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
zuul:
  routes:
  user-service:
    path: /user/**
    serviceId: user-service
    strip-prefix: false //去除路由前綴,默認為true,改為false即使user-serivce這條路由的/user路徑不做去除,發送給真實路徑,則訪問地址為127.0.0.1:10010/user/16,因為匹配路徑的/user/會發送給真實路徑,但使用此功能無法簡化路由條目配置
  ignored-services:  #這里是不路由的服務,書寫方式是集合的方式
    - consumer-service

 

過濾器:

ZuulFilter是過濾器的頂級父類。在這里我們看一下其中定義的4個最重要的方法:

public abstract ZuulFilter implements IZuulFilter{
​
    abstract public String filterType();
​
    abstract public int filterOrder();
    
    boolean shouldFilter();// 來自IZuulFilter
​
    Object run() throws ZuulException;// IZuulFilter
}
  • shouldFilter:返回一個Boolean值,判斷該過濾器是否需要執行。返回true執行,返回false不執行。

  • run:過濾器的具體業務邏輯。

  • filterType:返回字符串,代表過濾器的類型。包含以下4種:

    • pre:請求在被路由之前執行

    • routing:在路由請求時調用

    • post:在routing和errror過濾器之后調用

    • error:處理請求時發生錯誤調用

  • filterOrder:通過返回的int值來定義過濾器的執行順序,數字越小優先級越高。

 

過濾器執行的生命周期:

  • 正常流程:

    • 請求到達首先會經過pre類型過濾器,而后到達routing類型,進行路由,請求就到達真正的服務提供者,執行請求,返回結果后,會到達post過濾器。而后返回響應。

  • 異常流程:

    • 整個過程中,pre或者routing過濾器出現異常,都會直接進入error過濾器,再error處理完畢后,會將請求交給POST過濾器,最后返回給用戶。

    • 如果是error過濾器自己出現異常,最終也會進入POST過濾器,而后返回。

    • 如果是POST過濾器出現異常,會跳轉到error過濾器,但是與pre和routing不同的時,請求不會再到達POST過濾器了。

 

Zuul所有內置過濾器列表:

 

使用場景:

  • 請求鑒權:一般放在pre類型,如果發現沒有訪問權限,直接就攔截了

  • 異常處理:一般會在error類型和post類型過濾器中結合來處理。

  • 服務調用時長統計:pre和post結合使用。

 

自定義過濾器:

模擬一個登錄的校驗。

基本邏輯:如果請求中有access-token參數,則認為請求有效,放行。

@Component
public class LoginFilter extends ZuulFilter{
    @Override
    public String filterType() {
        // 登錄校驗,肯定是在前置攔截
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        // 該常量值為5 ,減1后為4
        return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1;
    }

    @Override
    public boolean shouldFilter() {
        // 返回true,代表過濾器生效。
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        // 登錄校驗邏輯。
        // 1)獲取Zuul提供的請求上下文對象
        RequestContext ctx = RequestContext.getCurrentContext();//RequestContext是一個Request域,此域的作用范圍是從請求到達zuul一直到路由結束返回到客戶端,整個完整流程都會存在
        // 2) 從上下文中獲取request對象
        HttpServletRequest req = ctx.getRequest();
        // 3) 從請求中獲取token
        String token = req.getParameter("access-token");
        // 4) 判斷
        if(StringUtils.isBlank(token)){ //StringUtils,需引apache的commons-lang3包的依賴 使用此方式可以避免內存溢出
            // 沒有token,登錄校驗失敗,攔截
            ctx.setSendZuulResponse(false);//true則放行,false則攔截
            // 返回403狀態碼。也可以考慮重定向到登錄頁。
            ctx.setResponseStatusCode(HttpStatus.Forbidden.value());
        }
        // 校驗通過,可以考慮把用戶信息放入上下文,繼續向后執行
        return null;//默認為空即為放行
    }
}

 此時使用http://127.0.0.1:10010/user/16 網頁會跳轉403

使用http://127.0.0.1:10010/user/16?access-token=1212121 即可正常訪問,此案例只是驗證access-token是否存在,不驗證access-token的正確性

 

Zuul的負載均衡ribbon和熔斷hystrix

 在zuul的配置文件中配置

server:
port: 10010
spring:
application:
name: zuul
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
zuul:
  routes:
  user-service:
    path: /user/**
    serviceId: user-service
    strip-prefix: false
  ignored-services:
    - consumer-service
zuul: retryable: true ribbon: ConnectTimeout: 250 # 連接超時時間(ms) ReadTimeout: 2000 # 通信超時時間(ms) OkToRetryOnAllOperations: true # 是否對所有操作重試 MaxAutoRetriesNextServer: 2 # 同一服務不同實例的重試次數 MaxAutoRetries: 1 # 同一實例的重試次數 hystrix: command: default: execution: isolation: thread: timeoutInMillisecond: 6000 # 熔斷超時時長:6000ms

由於ribbon一次訪問失敗后會自動重試一次,因此 ( ConnectTimeout + ReadTimeout ) × 2 < timeoutInMillisecond

即:

timeoutInMillisecond的真實值是: ( ConnectTimeout + ReadTimeout ) × 2

公式:

timeoutInMillisecond = ( ribbon ConnectTimeout + ribbon ReadTimeout ) * (maxAutoRetries + 1) * ( maxAutoRetriesNextServer + 1 );

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM