原文地址:https://www.iteye.com/blog/huan1993-2424676
我們知道我們前臺要展示數(shù)據(jù)給用戶看构订,這中間可能涉及到從后端的多個微服務進行獲取數(shù)據(jù)澎嚣。比如獲取用戶信息需要用到用戶微服務掐隐、獲取商品信息需要獲取商品微服務蓄喇、創(chuàng)建訂單需要調用訂單微服務殊橙,而各個微服務可能分布在各個機器上何暮,前端要獲取到數(shù)據(jù)就必須要知道各個微服務的地址裤园,這給前端增加開發(fā)的復雜性彼乌。一段后端的某個微服務地址改變了泻肯,前端可能還要修改。而且后端各個微服務權限認證也不好認證慰照,那么有沒有一種好的解決辦法呢灶挟?服務網(wǎng)關就正好可以解決這個問題,在 spring cloud 中使用的就是zuul來實現(xiàn)服務網(wǎng)關毒租。我們來看一下有了服務網(wǎng)關后稚铣,前端程序調用后端服務。
由上可知墅垮,當存在服務網(wǎng)關惕医,前端程序通過服務網(wǎng)關調用后臺服務,同時我們也可以在網(wǎng)關層進行各種操作算色,比如限流抬伺、權限校驗等。
實現(xiàn)功能
1灾梦、查看 zuul 中配置好的路由和過濾器信息
2峡钓、忽略所有微服務或某些微服務
3妓笙、忽略所有為服務,只路由指定的微服務
4能岩、通過path和url訪問到具體的某臺機器上
5寞宫、脫離eureka進行訪問,并使之具有負載均衡和隔離的機制等
6捧灰、轉發(fā)前是否去掉路由前綴
7淆九、為所有路由都增加一個通過的前綴
8、忽略某些路徑不進行路由
9毛俏、敏感頭的傳遞(比如Cookie等)全局設置和某個微服務設置
10炭庙、忽略頭
11、spring security 在classpath 下會忽略的頭
12煌寇、本地調換和路由的優(yōu)先級
13焕蹄、配置網(wǎng)關超時
14、重寫 Location 頭
15阀溶、文件上傳處理
代碼結構
eureka-server
|- 服務注冊中心
zuul
product-provider-8202
product-provider-8203
|- 服務提供者
product-consumer-8201
|- 服務消費者
product-gateway-8204
|- 網(wǎng)關程序腻脏,演示網(wǎng)關路由的各種配置
代碼編寫
一、服務提供者银锻、服務消費者永品、注冊中心,沒有什么需要特別注意的击纬,略鼎姐。
二、服務網(wǎng)關的編寫
1更振、創(chuàng)建網(wǎng)關工程
2炕桨、引入 zuul 的依賴
3、啟動類上增加 @EnableZuulProxy 注解
4肯腕、yml 文件上注冊到 eureka 上
三献宫、eureka服務啟動界面
功能實現(xiàn)
1、查看 zuul 中配置好的路由和過濾器信息
當我們啟動了zuul 的網(wǎng)關之后实撒,想知道當前zuul代理了那些路由姊途,訪問的路徑又是那些或者我們自己寫了一個zuul的filter,想知道它當前位于zuul的filter的那個位置時知态,該如何查詢捷兰。
**訪問路徑:** http://網(wǎng)關地址:端口/routes 訪問路由的簡單信息
http://網(wǎng)關地址:端口/routes?format=details 訪問路由的詳細信息
http://網(wǎng)關地址:端口/filters 訪問zuul中使用了那些過濾器。
**yml文件配置:**
Yml代碼::
management:
security:
enabled: false # 默認值是 true, 為true的話那么頁面上可能會報沒有權限訪問
不進行配置肴甸,訪問上面的2個端點會報沒有權限訪問寂殉。
2囚巴、忽略所有微服務或某些微服務
默認情況下原在,只要引入了zuul后友扰,就會自動一個默認的路由配置,但有些時候我們可能不想要默認的路由配置規(guī)則庶柿,想自己進行定義
**忽略所有微服務:(后面寫 * )**
zuul:
ignored-services: product-provider,product-consumer-8201
忽略某些微服務:(直接寫微服務的名字=>可以理解為spring.application.name的值村怪,多個以都好分隔)
zuul:
ignored-services: product-provider,product-consumer-8201
3、忽略所有為服務浮庐,只路由指定的微服務
訪問: http://gatewayhost:port/product/selectOne ===> 轉發(fā)到 product-provider上的selectOne
四甚负、通過path和url訪問到具體的某臺機器上
有時候我們測試的時候需要訪問到具體的某臺機器上,而不希望負載均衡到別的機器上或者需要訪問到第三方的某臺機器上审残。
zuul:
routes:
product-provider:
path: /product/**
url: http://localhost:8202/
注意:
1梭域、product-provider 這個值可以隨便寫,即使是一個不存在的值
2搅轿、這種方式訪問不會作為 HystrixCommand 來進行訪問病涨。
3、url 里面也不可以寫多個url
五璧坟、脫離eureka進行訪問既穆,并使之具有負載均衡和隔離的機制等
運行結果:
六、轉發(fā)前是否去掉路由前綴
七雀鹃、為所有路由都增加一個通過的前綴
有些時候我們系統(tǒng)所有的路由都有一個統(tǒng)一的前綴進行訪問幻工,此時就可以使用 zuul.prefix 進行統(tǒng)一添加。
八黎茎、忽略某些路徑不進行路由
有些時候囊颅,我們某些微服務的某些地址不希望被第三方客戶調用到,需要被隱藏起來工三,此時就可以使用網(wǎng)關路由這些url不進行路由迁酸。
zuul:
ignored-patterns: /**/selectOne/**
routes:
product-provider: /product/**
注意: 這個忽略是全局忽略,即對所有的微服務都進行忽略
九俭正、敏感頭的傳遞(比如Cookie等)全局設置和某個微服務設置
有些時候我們微服務上游可能想傳遞一些請求頭到下游的服務奸鬓,比如Token、Cookie等值掸读,默認情況下串远,zuul 不會將 Cookie,Set-Cookie,Authorization這三個頭傳遞到下游服務,如果需要傳遞儿惫,就需要忽略這些敏感頭澡罚。
全局和局部設置敏感頭:
運行結果:
注意:
1、可以看到訪問 product 路由時肾请,是可以獲取到 敏感頭中 cookie 的信息的留搔,訪問 consumer 路由無法獲取到。
2铛铁、如果下游服務啟用了hystrix隔显,那么 RequestInterceptor 要想從 ThreadLocal 中獲取request的值却妨,需要將隔離策略修改成信號量。
十括眠、忽略頭 (鏈接)
有些時候彪标,我們不想將某個頭傳遞到其它所有的微服務中,就可以使用忽略頭掷豺,忽略頭是全局配置的捞烟,如果想在某個服務中忽略某個頭,可以使用敏感頭忽略当船。
zuul:
routes:
product-provider:
path: /product/**
serviceId : product-provider
ignored-headers: token # 全局忽略頭题画,忽略 token 這個請求頭,不向下游服務傳遞這個token請求頭
zuul.ignored-headers: token** 表示被zuul路由的服務都不會傳遞 token 這個請求頭德频。
十一婴程、spring security 在classpath 下會忽略的頭
當我們的 spring security 在classpath中,zuul 會為我們增加一個默認的 spring security 相關的忽略頭抱婉,如果我們不想要忽略档叔,將 zuul. ignore-security-headers: false 就可以了。
# spring security 在classpath 下會忽略的頭
zuul:
routes:
product-provider:
path: /product/**
serviceId : product-provider
ignore-security-headers: false # 為true會忽略spring security安全頭蒸绩,如果下游需要用到需要設置成false
十二衙四、本地調換和路由的優(yōu)先級
有些時候,我們頁面上訪問到的某些路徑患亿,想讓網(wǎng)關直接進行處理传蹈,而不是直接轉發(fā)到后端的服務上,此時就可以使用到路由的跳轉步藕。 有些時候 ** /product/ext/**** 想路由到 product-provider-ext 服務上惦界,
/product/**** 想路由到 product-provider 服務上,此時在 yml 文件中順序配置**即可咙冗。
十三沾歪、配置網(wǎng)關超時
如果是通過 url 進行配置的,那么需要設置下面這個超時時間
十四雾消、重寫 Location 頭
如果Zuul面向Web應用程序灾搏,那么當Web應用程序通過http狀態(tài)代碼3XX重定向時,可能需要重寫Location頭立润,否則瀏覽器將最終重定向到Web應用程序的url而不是Zuul url狂窑。
十五、文件上傳處理
在微服務中桑腮,有時候我們經(jīng)常需要用到文件的上傳泉哈,當使用了服務網(wǎng)關 zuul 后,對于小的文件是可以上傳成功的,那么對于大的文件就會報錯丛晦,此處應該如何處理呢巨缘?
對于大文件的上傳,我們需要繞過 Spring 的 DispatcherServlet采呐。在 spring cloud zuul 中我們只需要在路由的前面加上 /zuul( zuul.servletPath) 前綴即可。
從上圖中可以看到搁骑,對于大文件的上傳斧吐,是加上了 /zuul 的前綴的。
完整代碼
服務網(wǎng)關配置代碼: https://gitee.com/huan1993/spring-cloud-parent/tree/master/zuul