Spring Cloud 在 Zuul 的 routing 階段實現了幾個過濾器,這些過濾器決定如何進行路由工作。
-
簡單路由(SimpleHostRoutingFilter)
該過濾器運行后,會將 HTTP 請求全部轉發到"源服務器",簡單路由的配置如下:
#zuul路由配置
zuul:
routes:
#表示http://localhost:9100/person/speaks地址,路由到http://localhost:8080/speaks
person:
path:/person/**
url:http://localhost:8080
該配置訪問 http://localhost:9200/person/speak 會將請求轉發到 http://localhost:8080/speak ,為了配置簡化,可以省略 path 屬性,簡化配置如下:
#zuul路由配置
zuul:
routes:
#表示http://localhost:9100/person/speaks地址,路由到http://localhost:8080/speaks
person:
url:http://localhost:8080
url 的值必須以 http: 和 https: 字符串開頭,否則不會觸發簡單路由。
簡單路由使用了 HttpClient 進行轉發,該過濾器會將 HttpServletRequest 的相關數據(HTTP方法,參數、請求頭等)轉換為 HttpClient 的請求實體,再使用 CloseableHttpClient 進行轉發,為了保證性能,使用了 HttpClient 的連接池功能,因此,在使用簡單路由時,可以配置 HttpClient 連接池的屬性:
- zuul.host.maxTotalConnections:目標主機的最大連接數,默認值 200。配置該屬性,相當與調用了 PoolingHttpClientConnectionManager 的 setMaxTotal 方法。
-
zuul.host.maxPerRouteConnections:每個主機的初始連接數,默認值 20。配置該屬性,相當與調用了PoolingHttpClientConnectionManager 的 setDefaultMaxPerRoute 方法。
-
跳轉路由(SendForwardFilter)
跳轉路由時當外部訪問網關的 A 地址時,會跳轉到 B 地址,處理跳轉的過濾器為 SendForwardFilter,跳轉路由的配置如下:
#zuul路由配置
zuul:
routes:
testRoute:
path:/test/**
url:forward:/hello
表示訪問 http://localhost:9100/test 地址時會自動跳轉到 http://localhost:9100/hello 地址,注意,這個不是客戶端跳轉,在瀏覽器上是無法看到地址變化的,只能根據返回信息來驗證,並且不能跨域名,只能在當前站點進行跳轉,在驗證跳轉路由還必須創建一個簡單的 REST 服務,如下:
package org.lixue.zuul;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloWorldController{
@RequestMapping(value="/hello/{name}",method=RequestMethod.GET)
publicStringhello(@PathVariable("name")Stringname){
return"hello"+name;
}
}
跳轉路由實現比較簡單,實際上是調用了 RequestDispatcher 的 forward 方法進行跳轉。
-
Ribbon 路由(RibbonRoutingFilter)
當網關作為 Eureka 客戶端注冊到 Eureka 服務器時,可以通過配置 serviceId 將請求轉發到集群的服務中,使用以下配置,可以執行 Ribbon 路由過濾器:
#zuul路由配置
zuul:
routes:
#表示http://localhost:9100/hello/speaks地址,路由到http://HELLOWORLD-PROVIDER/speaks,其中具體地址是通過eureka獲取
hello:
path:/hello/**
#或者使用url:HELLOWORLD-PROVIDER含義一樣
serviceId:HELLOWORLD-PROVIDER
與簡單路由一樣,serviceId 也可以被省略,當省略時,將會使用 routeId 作為 serviceId,簡化配置如下:
#zuul路由配置
zuul:
routes:
#表示http://localhost:9100/hello/speaks地址,路由到http://HELLOWORLD-PROVIDER/speaks,其中具體地址是通過eureka獲取
HELLOWORLD-PROVIDER:
path:/hello/**
如果配置了 serviceId 或者 url 的配置項不是簡單的路由格式(不以 http: 或 https:開頭),也不是跳轉路由格式(forward:開頭),那么就會執行 ribbon 路由過濾器,配置如下:
#zuul路由配置
zuul:
routes:
#表示http://localhost:9100/hello/speaks地址,路由到http://HELLOWORLD-PROVIDER/speaks,其中具體地址是通過eureka獲取
hello:
path:/hello/**
#或者使用url:HELLOWORLD-PROVIDER含義一樣
url:HELLOWORLD-PROVIDER
如果后端服務多達十幾個的時候,每一個都這樣配置也挺麻煩的,spring cloud zuul 已經幫我們做了默認配置,默認情況下,Zuul 會代理所有注冊到Eureka Server的微服務,並且 Zuul 的路由規則如下:
http://ZUUL_HOST:PORT/serviceId/**
如果想讓一個或多個服務被不路由,可以使用 zuul.ignoredServices 屬性來配置,如果設置 '*' 則表示所有服務被忽略,配置如下:
zuul:
#不被路由的serviceId,多個使用逗號分割
ignored-services:HELLOWORLD-PROVIDER
-
忽略路由
除了使用 zuul.ignoredServices 來忽略路由服務外,還可以使用 zuul.ignoredPatterns 來設置不進行路由的 Url,配置如下:
#zuul路由配置
zuul:
routes:
#表示http://localhost:9100/hello/speaks地址,路由到http://HELLOWORLD-PROVIDER/speaks,其中具體地址是通過eureka獲取
hello:
path:/hello/**
#或者使用url:HELLOWORLD-PROVIDER含義一樣
serviceId:HELLOWORLD-PROVIDER
ignored-patterns:/hello/noRoute
訪問/hello會被路由到HELLOWORLD-PROVIDER服務,但是/hello/noRoute不會被路由。
請求頭配置
在集群的服務間共享請求頭並沒有什么問題,但是如果請求會被轉發到其他系統,那么對於敏感的請求頭信息,就需要進行處理。在默認情況下,HTTP 請求頭的 Cookie、SetCookie、Authorization 屬性不會傳遞到"源服務",可以使用 sensitiveHeaders 屬性來配置敏感請求頭,下面的配置全局生效:
#zuul路由配置
zuul:
#HTTP請求頭不進行轉發
sensitive-headers:Cookie,Set-Cookie,Authorization
如果只希望針對一個路由生效,可以在路由下進行配置,如下:
#zuul路由配置
zuul:
routes:
#表示http://localhost:9100/hello/speaks地址,路由到http://HELLOWORLD-PROVIDER/speaks,其中具體地址是通過eureka獲取
hello:
path:/hello/**
#或者使用url:HELLOWORLD-PROVIDER含義一樣
serviceId:HELLOWORLD-PROVIDER
#HTTP請求頭不進行轉發
sensitive-headers:Cookie,Set-Cookie,Authorization
如果每一個路由都需要配置一些額外的敏感Header時,那你可以通過 zuul.ignoredHeaders 來統一設置需要忽略的HTTP請求頭,默認情況下,是沒有配置的,如果項目中引入了Spring Security,那么Spring Security會自動加上這個配置,默認值為: Pragma、Cache-Control、X-Frame-Options、X-Content-Type-Options、X-XSS-Protection、Expries。