Zuul(SpringCloud學習筆記一)
路由是微服務架構中必須(integral )的一部分,比如,“/” 可能對映到你的WEB程式上,”/api/users
“可能對映到你的使用者服務上,“/api/shop”可能對映到你的商品服務商。(註解:我理解這裡的這幾個對映就是說通過Zuul這個閘道器把服務對映到不同的服務商去處理,從而變成了微服務!)
Zuul是Netflix出品的一個基於JVM路由和服務端的負載均衡器.
Zuul功能:
- 認證
- 壓力測試
- 金絲雀測試
- 動態路由
- 負載削減
- 安全
- 靜態響應處理
- 主動/主動交換管理
Zuul的規則引擎允許通過任何JVM語言來編寫規則和過濾器, 支援基於Java和Groovy的構建。
配置屬性 zuul.max.host.connections
zuul.host.maxTotalConnections
(總連線數)和 zuul.host.maxPerRouteConnections
,(每個路由連線數) 預設值分別是200和20.
一 . Zuul做反向代理
當一個UI應用呼叫一個或更多的後端服務的時候,我們可以用Spring Cloud建立一個Zuul代理減少開發是非常常見的例子。使用代理服務來避免必須的跨域資源共享(Cross-Origin Resource Sharing)和所有的後端需要分別認證的問題。
在Spring Boot主函式上通過註解 @EnableZuulProxy
來開啟, 這樣可以讓本地的請求轉發到適當的服務. 按照約定, 一個ID為"users"的服務會收到 /users
Zuul starter沒有包含服務發現的客戶端, 所以對於路由你需要在classpath中提供一個根據service IDs做服務發現的服務.(例如, eureka是一個不錯的選擇)
在服務ID表示式列表中設定 zuul.ignored-services
, 可以忽略已經新增的服務. 如果一個服務匹配表示式, 則將會被忽略, 但是對於明確配置在路由匹配中的, 將不會被忽略, 例如:
application.yml
zuul:
ignoredServices: '*'
routes: users: /myusers/**
在這個例子中, 除了"users", 其他所有服務都被忽略了.
這個意味著http請求"/myusers"將被轉發到"users"服務(比如 "/myusers/101" 將跳轉到 "/101")
為了更細緻的控制一個路由, 你可以直接配置路徑和服務ID:
routes:
zuul:
users:
path: /myusers/**
serviceId: users_service
這個意味著 HTTP 呼叫"/myusers"被轉發到"users_service"服務. 路由必須配置一個可以被指定為ant風格表示式的"path", 所以“/myusers/*”只能匹配一個層級,
但"/myusers/**"可以匹配多級.
後端的配置既可以是"serviceId"(對於服務發現中的服務而言), 也可以是"url"(對於實體地址), 例如:
但"/myusers/**"可以匹配多級.
後端的配置既可以是"serviceId"(對於服務發現中的服務而言), 也可以是"url"(對於實體地址), 例如:
zuul:
routes:
users:
path: /myusers/**
url: http://example.com/users_service
這個簡單的"url-routes"不會按照 HystrixCommand
執行, 也無法通過Ribbon負載均衡多個URLs. 為了實現這一指定服務路由和配置Ribbon客戶端(這個必須在
Ribbon中禁用Eureka: 具體參考更多資訊), 例如:
zuul:
routes:
users:
path: /myusers/**
serviceId: users
ribbon:
eureka:
enabled: false
users:
ribbon:
listOfServers: example.com,google.com //所使用的Ribbon列表
你可以使用regexmapper提供serviceId和routes之間的繫結. 它使用正則表示式組來從serviceId提取變數, 然後注入到路由表示式中.
ApplicationConfiguration.java
@Bean
public PatternServiceRouteMapper serviceRouteMapper() {
return new PatternServiceRouteMapper(
"(?<name>^.+)-(?<version>v.+$)",
"${version}/${name}");
}
這個意思是說"myusers-v1"將會匹配路由"/v1/myusers/**". 任何正則表示式都可以, 但是所有組必須存在於servicePattern和routePattern之中. 如果servicePattern不匹配服務ID,則使用預設行為. 在上面例子中,一個服務ID為“myusers”將被對映到路徑“/ myusers/**”(沒有版本被檢測到) ,這個功能預設是關閉的,並且僅適用於服務註冊的服務。 設定zuul.prefix
可以為所有的匹配增加字首, 例如/api,代理字首預設會從請求路徑中移除(通過
zuul.stripPrefix=false
可以關閉這個功能).
- #反響代理配置
- #這裡的配置類似nginx的反響代理
- #當請求/api/**會直接交給listOfServers配置的伺服器處理
- #當stripPrefix=true的時候 (http://127.0.0.1:8181/api/user/list -> http://192.168.1.100:8080/user/list)
- #當stripPrefix=false的時候(http://127.0.0.1:8181/api/user/list -> http://192.168.1.100:8080/api/user/list)
- zuul.routes.api.path=/api/**
- zuul.routes.api.stripPrefix=false
- api.ribbon.listOfServers=192.168.1.100:8080,192.168.1.101:8080,192.168.1.102:8080
你也可以在指定服務中關閉這個功能:
zuul:
routes:
users:
path: /myusers/**
stripPrefix: false
在這個例子中, 請求"/myusers/101"將被跳轉到"users"服務的"/myusers/101"上.zuul.routes的鍵值隊
實際上繫結到型別為ZuulProperties
的物件上. 如果你檢視這個物件你會發現一個叫"retryable"的欄位, 設定為"true"會 使Ribbon 客戶端自動在失敗時重試(如果你需要修改重試引數, 直接使用Ribbon客戶端的配置)X-Forwarded-Host
請求頭預設在跳轉時新增. 通過設定zuul.addProxyHeaders = false
關閉它. 字首路徑預設剝離, 並且對於後端的請求通過請 求頭"X-Forwarded-Prefix"獲取(上面的例子中是"/myusers") 通過@EnableZuulProxy
應用程式可以作為一個獨立的服務, 如果你想設定一個預設路由("/"), 比如zuul.route.home: /
將路由所有的請求(例如: "/**") 到"home"服務.