至此,已實現基於Eureka的服務發現,基於Ribbon的負載均衡,Feign也爲咱們提供了很不錯的遠程調用能力,使用Hystrix後,高併發場景下應用也不會被別人拖死——我們的微服務架構已經日趨完善!git
然而,迄今爲止,只討論了微服務之間的調用,尚沒討論如何應對外部請求。應對外部請求時,就會發現,咱們的架構依然存在一些問題——github
不一樣的微服務通常會有不一樣的網絡地址,而外部客戶端(例如手機APP)可能須要調用多個服務的接口才能完成一個業務需求。例如一個電影購票的手機APP,可能會調用多個微服務的接口,才能完成一次購票的業務流程,以下圖所示。web
若是讓客戶端直接與各個微服務通訊,會有如下的問題:spring
以上問題可藉助微服務網關解決。微服務網關是介於客戶端和服務器端之間的中間層,全部的外部請求都會先通過微服務網關。使用微服務網關後,架構以下所示。數據庫
此時,微服務網關封裝了應用程序的內部結構,客戶端只須跟網關交互,而無須直接調用特定微服務的接口。這樣,開發就能夠獲得簡化。不只如此,使用微服務網關還有如下優勢:後端
Zuul是Netflix開源的微服務網關,它能夠和Eureka、Ribbon、Hystrix等組件配合使用。Zuul的核心是一系列的過濾器,這些過濾器幫助咱們完成如下功能:跨域
注1:以上介紹來自Zuul官方文檔,但其實開源版本的Zuul以上功能一個都沒有——開源的Zuul只是幾個Jar包而已,以上能力指的應該是Netflix官方自用的Zuul的能力。瀏覽器
注2:Netflix自用的Zuul能力是比較強大的,可以使用Groovy編寫過濾器,而且可動態加載/卸載、修改規則,並且使用Cassandra做爲數據庫,然而開源版本這些一個都沒有。安全
注3:Spring Cloud中,Zuul絕大部分功能都是Spring Cloud團隊爲Zuul開發的。服務器
注4:因此Zuul 2.x的開源進度延後一年,Spring Cloud團隊開發了本身的Spring Cloud Gateway,並宣佈Spring Cloud不打算支持Zuul 2.x,你還以爲意外嗎?
注5:看到這裏,不少人可能沒有動力學習Zuul了,我的認爲仍是能夠了解一下的,後面講到Spring Cloud Gateway時,你會發現不少設計理念是相通的。
Spring Cloud對Zuul進行了整合與加強。目前,Zuul使用的默認HTTP客戶端是Apache HTTP Client,也可使用RestClient或者okhttp3.OkHttpClient
。 若是想要使用RestClient,能夠設置ribbon.restclient.enabled=true
;想要使用okhttp3.OkHttpClient
,能夠設置ribbon.okhttp.enabled=true
。
TIPS
Zuul的GitHub:https://github.com/Netflix/zuul
下面經過一個簡單的例子幫助你們快速入門Zuul。
加依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
加註解:@EnableZuulProxy
寫配置:
server: port: 8040 spring: application: name: microservice-gateway-zuul eureka: client: service-url: defaultZone: http://localhost:8761/eureka/
由代碼可知,咱們編寫了一個Zuul,並將其註冊到了Eureka上。
啓動多個應用,Eureka Server上展現以下:
http://127.0.0.1:8040/microservice-provider-user/users/1
,會發現請求被轉發到了microservice-provider-user
服務的/users/1
端點;http://127.0.0.1:8040/microservice-consumer-movie/movies/users/1
,發現請求被轉發到了microservice-consumer-movie
服務的/movies/users/1
端點;屢次訪問訪問http://127.0.0.1:8040/microservice-provider-user/users/1
,會發現兩個microservice-provider-user
都會打印相似以下的日誌:
Hibernate: select user0_.id as id1_0_0_, user0_.age as age2_0_0_, user0_.balance as balance3_0_0_, user0_.name as name4_0_0_, user0_.username as username5_0_0_ from user user0_ where user0_.id=? ...
在application.yml
中添加以下配置後,並重啓Zuul:
management: endpoints: web: exposure: include: '*' endpoint: health: show-details: always
此時,此時訪問http://localhost:8040/actuator/health
,可看到相似以下結果:
{ ... "hystrix":{"status":"UP"} }
而且,當Zuul轉發API後,訪問http://localhost:8040/actuator/hystrix.stream
可看到相似以下的信息:
data: {"type":"HystrixCommand","name":"microservice-provider-user",.....}
說明Zuul整合了Hystrix。
http://www.itmuch.com/spring-cloud/finchley-16/