【springcloud】Zuul高級配置(zuul--2)


 轉自:https://blog.csdn.net/pengjunlee/article/details/87162192

自定義路由規則

在《API Gateway 的路由和過濾(Zuul)》一章中,我們並未對Zuul的路由規則進行設置,默認會使用服務的 ID 對服務進行路由,即:在源服務的URI之前增加 /service-id 前綴。

# Zuul 默認路由地址
http://<zuul-host>:<zuul-port>/service-id/[service-URI]

 

除了可以直接使用默認的路由規則外,Zuul還提供了很多配置項允許我們對路由映射規則進行自定義,例如:

zuul:
  ignoredServices: '*'
  routes:
    message-service: /zuul-msg/**

 

示例中這個配置的作用是:忽略除 message-service 外的所有服務(不對它們進行路由),只將message-service 服務路由到 /zuul-msg/** 地址上。

zuul.ignored-services  # 忽略指定微服務,多個微服務之間使用逗號分隔
zuul.routes.service-id # 指定service-id服務的路由地址

 

 注意:在 zuul.routes 中配置了的服務,即使被包含在 zuul.ignored-services 配置中也不會被忽略。

若將上例中的配置改成如下,則表示除 message-service 外的所有服務都使用默認的路由規則。

zuul:
  routes:
    message-service: /zuul-msg/**

 

如果你希望對某一個路由進行更精細的控制,可以獨立地指定該服務的路由地址和它的service-id,例如:

zuul:
  routes:
    message: 
      path: /zuul-msg/**
      serviceId: message-service

 

或者,像下面這樣指定一個該服務的物理地址來替代上例中的service-id:

zuul:
  routes:
    message: 
      path: /zuul-msg/**
      url: http://localhost:8771/

 

連續多次訪問 http://localhost:8791/zuul-msg/api/v1/msg/get 返回結果相同,見下圖:

 

可以看出,通過url配置的路由不會被當作HystrixCommand執行,自然也就不會使用Ribbon在多個Url之間進行負載均衡。所以,推薦使用serviceId進行配置。或者,指定一個包含有多個可用服務列表的serviceId,例如:

zuul:
  routes:
    message: 
      path: /zuul-msg/**
      serviceId: msg-servers
      
hystrix:
  command:
    msg-servers:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 1000
      
msg-servers:
  ribbon:
    NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
    listOfServers: http://localhost:8771/,http://localhost:8772/
    ConnectTimeout: 1000
    ReadTimeout: 3000
    MaxTotalHttpConnections: 500
    MaxConnectionsPerHost: 100

 

還有另外一種方法也可以達到上述目標:使用service-id為要路由的服務指定一個Ribbon客戶端,並設置Ribbon禁用Eureka,例如:

zuul:
  routes:
    message: 
      path: /zuul-msg/**
      serviceId: msg-servers
      
ribbon:
  eureka:
    enabled: false
 
msg-servers:
  ribbon:
    listOfServers: http://localhost:8771/,http://localhost:8772/

 

如果你的service-id命名滿足一定的規則,可以使用正則表達式從service-id中提取一些變量作為你的路由地址,例如:

	@Bean
	public PatternServiceRouteMapper serviceRouteMapper() {
		return new PatternServiceRouteMapper("(?<name>^.+)-(?<version>v.+$)", "${version}/${name}");
	}

 

在這個示例中,一個名稱為myusers-v1的服務會被路由到 /v1/myusers/** 地址上。在這里你可以使用任意正則表達式,但是要保證所有的命名組必須都包含servicePattern和routePattern兩部分。如果servicePattern不匹配service-id,就會使用默認的規則,即在服務原有的URI之前增加 /service-id 前綴。Zuul的這一特性默認是關閉的,而且只能被應用到已經發現的服務。

對那些要忽略的微服務也可以采用模式匹配進行更加精細的控制,例如:

zuul:
  ignoredPatterns: /**/v2/**
  routes:
    message-service: /zuul-msg/**

該例中的配置會忽略所有包含 /v2/ 的請求。 

使用 zuul.prefix 配置項可以為所有的路由地址都添加一個前綴,例如 /abc 。

zuul:
  prefix: /abc
  routes:
    message-service: /zuul-msg/** 

 

添加前綴之后路由地址為:http://localhost:8791/abc/zuul-msg/api/v1/msg/get 。 

 

 默認情況下,Zuul代理會在將請求轉發出去之前先將其中的前綴字符串剔除掉。如果你不想剔除前綴,可以設置 zuul.stripPrefix=false。如果你只是想不剔除指定某一個服務中的前綴,可以使用如下配置:

zuul:
  prefix: /abc
  # stripPrefix: false
  routes:
    message-service: /zuul-msg/**
    stripPrefix: false

 

zuul.routes 中的配置條目最終都會被綁定到一個ZuulProperties類型的對象,在 ZuulProperties 中還有一個 retryable 標識,將該標識設置成 ture 能夠讓Ribbon客戶端對失敗的請求自動進行重試。

zuul.routes 中配置的路由地址最終都會被存儲在一個Map中,路由的地址即為Map的key,Map的value是一個ZuulRoute類型的對象。在yaml配置文件中,路由地址相同的兩個服務,后面的會覆蓋前面的配置,從而導致先配置的服務不可用。

注意:如果需要保留路由的順序,需要使用yaml文件,因為使用properties文件時會丟失順序。

目前,Zuul已經使用 Apache HTTP Client 替換掉了已經過時的Ribbon RestClient 來作為自己的HTTP Client。你若想繼續使用 RestClient 或者 okhttp3.OkHttpClient,只需要將 ribbon.restclient.enabled 或者 ribbon.okhttp.enabled 設置為 true 即可。當然,你也可以使用自定義的 Apache HTTP client 或者 OK HTTP client,提供一個相應的 ClosableHttpClient 或者OkHttpClient 類型的 Bean即可。

設置請求頭

默認情況下,Zuul會為轉發的請求添加一些 X-Forwarded-* 請求頭,可以通過配置項 zuul.addProxyHeaders = false 來關閉它。請求中的前綴默認會被剔除,同樣地,請求中的X-Forwarded-Prefix 請求頭也會被摘取出來。

在同一個系統中,請求頭在多個服務之間是可以共享的,但是你可能並不希望某些敏感的請求頭信息泄露到下游的外部服務器,你可以把這些敏感請求頭配置到zuul.sensitiveHeaders列表,從而禁止它們被傳遞到下游。例如:

zuul:
  sensitiveHeaders: Cookie,Set-Cookie,Authorization
  routes:
    message-service: /zuul-msg/**
    sensitiveHeaders: token

 

sensitiveHeaders就相當於是一個向下游傳遞的請求頭黑名單,默認包含了 Cookie,Set-Cookie和Authorization三個請求頭。因此,如果你需要向下傳遞所有的請求頭信息,需要明確地把sensitiveHeaders設置成一個空列表,如下:

zuul:
  sensitiveHeaders: 
  routes:
    message-service: /zuul-msg/**

 

另外,你還可以把那些不需要傳遞到下游的請求頭或響應頭配置到 zuul.ignoredHeaders 中,可以達到相同的作用。默認情況下,當類路徑中不包含 Spring Security 時,ignoredHeaders 列表是空的;當類路徑中包含 Spring Security時,ignoredHeaders 列表會被初始化包含一些由Spring Security指定的 security 頭信息,例如 involving caching。這種情況下如果你需要把這些 security 頭信息傳遞到下游,可以添加 zuul.ignoreSecurityHeaders = false 配置項。

管理終端

默認情況下,當@EnableZuulProxy與Actuator一起使用時,Actuator健康監控頁面會增加兩個終端:Routes和Filters。

需要在pom.xml中引入Actuator依賴:

		<!-- Actuator 依賴 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>

 

並在application.yml文件中增加配置:

management:
  security:
    enabled: false
  endpoints:
    web:
      exposure:
        include: hystrix.stream,*

 

訪問 /actuator/routes 終端會返回一個映射路由的列表,如下圖。

 

訪問 /actuator/routes/details 終端會返回一個映射路由的詳細信息列表,如下圖。

 

訪問 /actuator/filters 終端會返回一個包含了過濾器類型和配置的Map對象。

 

編碼設置

  在對進來的請求進行處理的時候,請求參數會被解碼以便在Zuul過濾器中能夠對它們進行一些修改,然后又會在路由過濾器中重新編碼並發送出去,重新編碼后的結果跟原來的輸入可能會有所不同,這在多數情況下是沒什么問題的,但是在一些對復雜的請求字符串編碼比較挑剔的Web服務器中仍有可能會出問題。解決的辦法就是添加如下的配置來強制使用原始編碼的請求字符串,相當於直接使用 HttpServletRequest.getQueryString()方法來獲取請求字符串。

  在對進來的請求進行處理的時候,會先對請求的URI進行解碼,再和路由地址進行匹配,然后又會在路由過濾器中對請求的URI重新編碼並發送給后端,當你的URI中包含 “/” 字符時這可能會引發一些意想不到的問題。解決的辦法就是添加如下的配置來強制使用原始編碼的請求URI,相當於直接使用 HttpServletRequest.getRequestURI()方法來獲取請求URI。

禁用Zuul過濾器

Spring Cloud的Zuul自帶了一些過濾器Bean,默認情況下它們都是啟用的。如果你想禁用其中的某一個過濾器,可以使用如下配置: 

zuul.<SimpleClassName>.<filterType>.disable=true

 

按照慣例,過濾器所在包名中 “filters” 字符串后面的就是過濾器的類型了,例如,禁用 org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter ,配置如下:

zuul.SendResponseFilter.post.disable=true

 

超時設置

如果你需要設置通過Zuul路由的請求的Socket超時時間和Read超時時間,有兩種配置方法,需要根據你的配置情況進行選擇:

如果使用了服務發現,使用ribbon.ReadTimeout 和 ribbon.SocketTimeout 進行配置。

如果是通過指定URL的方式進行路由,使用zuul.host.connect-timeout-millis 和 zuul.host.socket-timeout-millis進行配置。

參考文章
https://github.com/spring-projects/spring-retry

https://cloud.spring.io/spring-cloud-netflix/single/spring-cloud-netflix.html#netflix-zuul-starter


免責聲明!

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



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