上篇文章咱們介紹了API網關的基本構建方式以及請求過濾,小夥伴們對Zuul的做用應該已經有了一個基本的認識,可是對於路由的配置咱們只是作了一個簡單的介紹,本文咱們就來看看路由配置的其餘一些細節。spring
本文是Spring Cloud系列的第二十篇文章,瞭解前十九篇文章內容有助於更好的理解本文: api
1.使用Spring Cloud搭建服務註冊中心
2.使用Spring Cloud搭建高可用服務註冊中心
3.Spring Cloud中服務的發現與消費
4.Eureka中的核心概念
5.什麼是客戶端負載均衡
6.Spring RestTemplate中幾種常見的請求方式
7.RestTemplate的逆襲之路,從發送請求到負載均衡
8.Spring Cloud中負載均衡器概覽
9.Spring Cloud中的負載均衡策略
10.Spring Cloud中的斷路器Hystrix
11.Spring Cloud自定義Hystrix請求命令
12.Spring Cloud中Hystrix的服務降級與異常處理
13.Spring Cloud中Hystrix的請求緩存
14.Spring Cloud中Hystrix的請求合併
15.Spring Cloud中Hystrix儀表盤與Turbine集羣監控
16.Spring Cloud中聲明式服務調用Feign
17.Spring Cloud中Feign的繼承特性
18.Spring Cloud中Feign配置詳解
19.Spring Cloud中的API網關服務Zuul緩存
首先咱們來回憶一下上篇文章咱們配置路由規則的那兩行代碼:服務器
zuul.routes.api-a.path=/api-a/** zuul.routes.api-a.serviceId=feign-consumer
咱們說當個人訪問地址符合/api-a/**規則的時候,會被自動定位到feign-consumer服務上去,不過兩行代碼有點麻煩,咱們能夠用下面一行代碼來代替,以下:app
zuul.routes.feign-consumer=/api-a/**
zuul.routes後面跟着的是服務名,服務名後面跟着的是路徑規則,這種配置方式顯然更簡單。
若是映射規則咱們什麼都不寫,系統也給咱們提供了一套默認的配置規則,默認的配置規則以下:負載均衡
zuul.routes.feign-consumer.path=/feign-consumer/** zuul.routes.feign-consumer.serviceId=feign-consumer
默認狀況下,Eureka上全部註冊的服務都會被Zuul建立映射關係來進行路由,可是對於我這裏的例子來講,我但願提供服務的是feign-consumer,hello-service做爲服務提供者只對服務消費者提供服務,不對外提供服務,若是使用默認的路由規則,則Zuul也會自動爲hello-service建立映射規則,這個時候咱們能夠採用以下方式來讓Zuul跳過hello-service服務,不爲其建立路由規則:url
zuul.ignored-services=hello-service
有的小夥伴可能爲有疑問,咱們定義路由規則/api-a/**
的時候,爲何最後面是兩個*,一個可不能夠呢?固然能夠,不過意義可就不同了,Zuul中的路由匹配規則使用了Ant風格定義,一共有三種不一樣的通配符:spa
通配符 | 含義 | 舉例 | 解釋 |
---|---|---|---|
? | 匹配任意單個字符 | /feign-consumer/? | 匹配/feign-consumer/a,/feign-consumer/b,/feign-consumer/c等 |
* | 匹配任意數量的字符 | /feign-consumer/* | 匹配/feign-consumer/aaa,feign-consumer/bbb,/feign-consumer/ccc等,沒法匹配/feign-consumer/a/b/c |
** | 匹配任意數量的字符 | /feign-consumer/* | 匹配/feign-consumer/aaa,feign-consumer/bbb,/feign-consumer/ccc等,也能夠匹配/feign-consumer/a/b/c |
有的時候咱們還會遇到這樣一個問題,好比我有兩個服務,一個叫作feign-consumer,還有一個叫作feign-consumer-hello,此時個人路由配置規則可能這樣來寫:日誌
zuul.routes.feign-consumer.path=/feign-consumer/** zuul.routes.feign-consumer.serviceId=feign-consumer zuul.routes.feign-consumer-hello.path=/feign-consumer/hello/** zuul.routes.feign-consumer-hello.serviceId=feign-consumer-hello
此時我訪問feign-consumer-hello的路徑會同時被這兩條規則所匹配,Zuul中的路徑匹配方式是一種線性匹配方式,即按照路由匹配規則的存儲順序依次匹配,所以咱們只須要確保feign-consumer-hello的匹配規則被先定義feign-consumer的匹配規則被後定義便可,可是在properties文件中咱們不能保證這個前後順序,此時咱們須要用YAML來配置,這個時候咱們能夠刪掉resources文件夾下的application.properties,而後新建一個application.yml,內容以下:code
spring: application: name: api-gateway server: port: 2006 zuul: routes: feign-consumer-hello: path: /feign-consumer/hello/** serviceId: feign-consumer-hello feign-consumer: path: /feign-consumer/** serviceId: feign-consumer eureka: client: service-url: defaultZone: http://localhost:1111/eureka/
這個時候咱們就能夠確保先加載feign-consumer-hello的匹配規則,後加載feign-consumer的匹配規則。
上文咱們說了一個zuul.ignored-services=hello-service屬性能夠忽略掉一個服務,不給某個服務設置映射規則,這個配置咱們能夠進一步細化,好比說我不想給/hello接口路由,那咱們能夠按以下方式配置(後面我都用yaml配置):
zuul: ignored-patterns: /**/hello/**
此時訪問/hello接口就會報404錯誤,同時咱們也能夠看到後臺打印以下日誌:
此外,咱們也能夠統一的爲路由規則增長前綴,設置方式以下:
zuul: prefix: /myapi
此時咱們的訪問路徑就變成了http://localhost:2006/myapi/f...。
通常狀況下API網關只是做爲系統的統一入口,可是有的時候咱們可能也須要在API網關上作一點業務邏輯操做,好比我如今在api-gateway項目中新建以下Controller:
@RestController public class HelloController { @RequestMapping("/local") public String hello() { return "hello api gateway"; } }
我但願用戶在訪問/local時可以自動跳轉到這個方法上來處理,那麼此時咱們須要用到Zuul的本地跳轉,配置方式以下:
zuul: prefix: /myapi ignored-patterns: /**/hello/** routes: local: path: /local/** url: forward:/local
此時訪問http://localhost:2006/myapi/l...結果以下:
咱們在使用Nginx的時候,會涉及到一個請求頭信息的配置,防止頁面重定向後跳轉到上游服務器上去,這個問題在Zuul中同樣存在,假設個人feign-consumer中提供了一個接口/hello4,當訪問/hello4接口的時候,頁面重定向到/hello,默認狀況下,重定向的地址是具體的服務實例的地址,而不是API網關的跳轉地址,這種作法會暴露真實的服務地址,因此須要在Zuul中配置,配置方式很簡單,以下:
zuul: add-host-header: true
表示API網關在進行請求路由轉發前爲請求設置Host頭信息。
默認狀況下,敏感的頭信息沒法通過API網關進行傳遞,咱們能夠經過以下配置使之能夠傳遞:
zuul: routes: feign-consumer: sensitiveHeaders:
在Zuul中,Ribbon和Hystrix的配置仍是和以前的配置方式一致,這裏我就不贅述了,若是咱們想關閉Hystrix重試機制,能夠經過以下方式:
關閉全局重試機制:
zuul: retryable: false
關閉某一個服務的重試機制:
zuul: routes: feign-consumer: retryable: false
關於Zuul中路由的配置細節咱們就說到這裏,有問題歡迎留言討論。
更多JavaEE資料請關注公衆號: