服務網關Zuul
學習筆記
路由是微服務架構不可或缺的一部分。例如,
/
可能被映射到您的Web應用程序,/api/users
被映射到用戶服務以及/api/shop
被映射到商店服務。 Zuul是Netflix
提供的基於JVM
的路由器和服務器端負載平衡器使用服務網關做統一入口和統一認證,他可以和Eureka,Ribbon,Hystrix等組件配合使用。Zuul組件的核心是一系列的過濾器!
配置統一入口
1. 創建模塊SpringBoot_Zuul
並引入依賴:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
</dependencies>
2. 創建包與啓動類: 並加上@EnableZuulProxy註解啓用網關
@SpringBootApplication
@EnableZuulProxy
public class ApplicationZuul {
public static void main(String[] args) {
SpringApplication.run(ApplicationZuul.class, args);
}
}
3.創建application.yml
配置文件,並將zuul
模塊註冊上去註冊中心並配置網關相關轉發配置
Zuul
啓動程序不包括髮現客戶端,因此,對於基於服務ID的路由,您還需要在類路徑上提供其中之一(Eureka是一種選擇)
server:
port: 8080 #指定端口
spring:
application:
name: eureka-zuul #指定服務名
eureka:
client:
serviceUrl: #註冊到註冊中心
defaultZone: http://127.0.0.1:8761/eureka/
instance:
prefer-ip-address: true
zuul:
prefix: /api #可配請求前綴
routes: #轉發配置
springBoot-client: # 名稱可以隨便寫 但最好見名思意
#配置請求URL的請求規則 請求只要是這個地址:http://localhost:8080/client/....
#開頭就去eureka-client模塊找
path: /client/**
#指定Eureka註冊中心中的服務id
serviceId: eureka-client
tensquare-test: #test模塊
path: /test/** #配置請求URL的請求規則 請求只要是這個地址開頭就去eureka-test模塊找
serviceId: eureka-test #指定Eureka註冊中心中的服務id
..........................
ribbon: #調用超時配置
ConnectTimeout: 5000
ReadTimeout: 5000
4.啓動測試是否配置好了統一入口,訪問http://localhost:8080/client/getss?id=888888888 看看是否是去eureka-client模塊調用服務
zuul
內部集成了ribbon
,會自動負載均衡的方式去調用部署多態相同的內部服務
5. zuul
的配置項說明:
1. - zuul.ignored-services
: 說明
在不用**
zuul.ignored-services
:配置項的時候:
你不想向外界暴露除你配置的隱射之外的服務就可以使用zuul.ignored-services
😗*
zuul:
routes:
springBoot-Client:
path: /client/**
serviceId: eureka-client
retryable: true
ignored-services: '*' #除了配置好的路由`path`訪問,其他一切通過路由服務名訪問都不通過
----------------------
ignored-services: #本身是個集合,可以配置多個忽略服務,其他沒忽略的可以訪問
- eureka-test
----------------------
ignored-services: eureka-test,eureka-Service #也可以用','隔開配置多個
2 .-zuul.prefix:
爲所有請求配置請求前綴
3**-zuul.retryable:
**(請求重試)
設置爲true
使自動重試失敗的請求,也可以爲單獨路由進行配置``zuul.routes.MyspringBoot-Client.retryable
還可以修改使用客戶端配置的重試操作的參數,在筆記2重試有介紹! 開啓這個功能前提需要引用spring-retry
的依賴
4. -zuul.ignored-patterns
: 該配置可以忽略特定路徑後面的所有的請求:
zuul: routes: springBoot-test: path: /test/** serviceId: eureka-test springBoot-Client: path: /client/** serviceId: eureka-client ignored-patterns: /**/list/**
上面表示訪問路徑
端口:/xxxx/list/xxxx
,/list/
後面的所有請求都會被忽略,例如:
http://localhost:8080/client/list
與http://localhost:8080/client/list/map
都訪問不了
5.-Zuul的Http客戶端
支持Apache Http、Ribbon的RestClient和OkHttpClient,現在默認使用Apache HTTP客戶端。如果要使用``RestClient
或,OkHttpClient
,
# 啓用Ribbon的RestClient ribbon.restclient.enabled=true # 啓用OkHttpClient ribbon.okhttp.enabled=true
使用
OkHttpClient
需要注意在你的項目中已經包含com.squareup.okhttp3
相關包
6.-Zuul.sensitive-headers:
該配置可以設置忽略的請求頭(解決請求沒有cookie與Authorization)
zuul: #全局 ....... sensitive-headers: Cookie,Set-Cookie,Authorization #忽略這些請求頭,該配置也是默認的,默認是不爲空的! ----------------------- zuul: routes: springBoot-Client: path: /client/** serviceId: eureka-client retryable: true sensitive-headers: Authorization,Cookie #也可以配置在單獨路由上
如果
sensitiveHeaders
在單獨路徑上設置了,則它將覆蓋全局sensitiveHeaders
設置!因爲默認就是忽略掉請求頭
Cookie,Set-Cookie,Authorization
,所以會請求會丟失掉cookie,Authorization
, 如果想發送請求帶上這些請求頭,則將該配置設置爲空,例如:zuul: routes: springBoot-Client: path: /client/** serviceId: eureka-client retryable: true sensitive-headers: #設置留空
7.-Zuul.force-original-query-string-encoding
查詢字符串編碼
處理傳入的請求時,查詢參數被解碼,因此可以在
Zuul
過濾器中進行修改。然後在路由過濾器中構建後端請求時重新編碼它們。如果使用Javascript
的encodeURIComponent()
方法編碼,結果可能與原始輸入不同。雖然這在大多數情況下不會出現任何問題,但一些Web服務器可以用複雜查詢字符串的編碼來挑選。要強制查詢字符串的原始編碼,可以將特殊標誌傳遞給
ZuulProperties
,以便查詢字符串與HttpServletRequest::getQueryString
方法相同:
application.yml
zuul: forceOriginalQueryStringEncoding: true #默認是false
**注意:**此特殊標誌僅適用於
SimpleHostRoutingFilter
,您可以使用RequestContext.getCurrentContext().setRequestQueryParams(someOverriddenParameters)
輕鬆覆蓋查詢參數,因爲查詢字符串現在直接在原始的HttpServletRequest
上獲取。
8. -禁用Zuul
過濾器
Spring Cloud的Zuul在代理和服務器模式下默認啓用了多個
ZuulFilter
bean。有關啓用的可能過濾器,請參閱zuul過濾器包。如果要禁用它,只需設置zuul...disable=true
。按照慣例,filters
之後的包是Zuul過濾器類型。例如,禁用org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter
設置zuul.SendResponseFilter.post.disable=true
9. - Zuul
超時
如果要爲通過
Zuul
代理的請求配置套接字超時和讀取超時,則根據您的配置,有兩個選項:
- 如果
Zuul
使用服務發現(serviceId
),則需要使用ribbon.ReadTimeout
和ribbon.SocketTimeout
功能區屬性配置這些超時 。如果通過指定URL配置了
Zuul
(url)路由,則需要使用zuul.host.connect-timeout-millis
和zuul.host.socket-timeout-millis
。
10. - 重定向與請求轉發問題解決
如果
Zuul
在Web應用程序的前面,則Location
當Web應用程序通過HTTP狀態代碼重定向時,您可能需要重新編寫標頭3XX
。否則,瀏覽器將重定向到Web應用程序的URL,而不是Zuul URL
。您可以配置LocationRewriteFilter
Zuul過濾器以將Location
標頭重寫爲Zuul
的URL。它還添加回去的全局前綴和特定於路由的前綴。以下示例通過使用Spring Configuration文件添加過濾器:@Configuration public class ZuulConfig { @Bean public LocationRewriteFilter locationRewriteFilter() { return new LocationRewriteFilter(); } //return "redirect:/test"; 重定向寫法 不用加路由`path`前綴路徑 //return "forward:/test"; 轉發寫法 }
小心使用此過濾器。篩選器作用於
Location
所有3XX
響應代碼的標頭,這可能不適用於所有情況,例如,將用戶重定向到外部URL時!上面的解決重定向方式好處在與控制層可以直接寫
api
方法的路徑,不用加路由前綴路徑,缺點是不能重定向到外部url
;(推薦使用方式)要重定向到外部
URL
可以使用另一種方式:zuul: routes: springBoot-Client: path: /client/** serviceId: eureka-client retryable: true add-host-header: true #配置上加上>>>添加主機頭
然後在控制層寫重定向路徑時要加上路由前綴:
return "redirect:/client/test";
||return "forward:/client/test";
11.- 路由跨域請求
默認情況下,
Zuul
將所有跨源請求(CORS)路由到服務。如果您想讓Zuul處理這些請求,可以通過提供自定義WebMvcConfigurer
bean 來完成:@Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/path-1/**") .allowedOrigins("https://allowed-origin.com") .allowedMethods("GET", "POST"); } }; }
在上面的示例中,我們允許
GET
和POST
從的方法allowed-origin.com
將跨域請求發送到以開頭的端點path-1
。您可以使用/**
映射將CORS
配置應用於特定的路徑模式或整個應用程序的全局路徑。您可以自定義屬性:allowedOrigins
,allowedMethods
,allowedHeaders
,exposedHeaders
,allowCredentials
並maxAge
通過此配置。
擴展資料:
網關官網文檔:
如果要爲通過Zuul代理的請求配置套接字超時和讀取超時,則根據您的配置,有兩種選擇:
- 如果Zuul使用服務發現,則需要使用
ribbon.ReadTimeout
和ribbon.SocketTimeout
功能區屬性配置這些超時 。
如果通過指定URL配置了Zuul路由,則需要使用 zuul.host.connect-timeout-millis
和zuul.host.socket-timeout-millis
。