我們在第一章《 Spring Cloud實戰(一):微服務注冊與微服務發現》中,講述了微服務注冊與微服務發現,但是對使用者來說,每個微服務都有自己獨立的入口與通路位址,通路起來實在太不友善,是以我們需要一個統一的入口,協同它們應付所有的通路請求。或者簡單來說,我們需要為所有的微服務建立一個代理,就類似于nginx伺服器那樣,是以今天就要請出我們的主角——ZUUL。
1. 建立項目
建立MAVEN項目,并引入zuul依賴,如下:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<!-- 千萬不要省略此依賴 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
為了降低Spring Cloud項目配置的複雜程度,強烈建議采用MAVEN子產品的模式,就如本人的示例項目所示。在上面的配置中,最容易犯錯的就是省略了第二個依賴,導緻“Forwarding error”錯誤,如下:
com.netflix.zuul.exception.ZuulException: Forwarding error
Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: ASSET
at com.netflix.loadbalancer.LoadBalancerContext.getServerFromLoadBalancer(LoadBalancerContext.java:) ~[ribbon-loadbalancer-.jar:]
at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:) ~[ribbon-loadbalancer-.jar:]
at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:) ~[ribbon-loadbalancer-.jar:]
再強調一遍,zuul伺服器要讀取eureka注冊的微服務,必須自己也要作為eureka的用戶端,是以必定要配置eureka依賴。
2. 建立配置檔案
在resources檔案夾中,添加application.yml,隻需要配置如下内容:
# 統一通路端口
server:
port:
zuul:
# 禁止服務自動添加
ignoredServices: '*'
# 手動添加服務
routes:
# 需要映射的微服務位址
asset:
path: /asset/**
# 可忽略,伺服器會自動發現
serviceId: ASSET
# 關鍵配置項
stripPrefix: false
上面的配置已經足夠支援zuul+eureka的運作了,zuul會自動發現所有的eureka服務,也就是說,zuul伺服器會自動拉取eureka注冊的微服務,如果需要将eureka配置得更加詳細點,還可以添加如下内容:
eureka:
client:
# 千萬不要手賤把它設成false
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
更多配置項請參見配置檔案,僅供參考。
在很多網上的執行個體中,很多人都把“eureka.client.fetch-registry”設定為false,結果我花費了整整一上午才調試找到這個錯誤。
3. 編寫ZUUL主類
啟動zuul服務非常簡單,隻需要添加如下主類,并以主函數啟動即可,如下:
@SpringBootApplication
@EnableZuulProxy
public class ZuulServerApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(ZuulServerApplication.class).web(true).run(args);
}
}
現在從8000端口(請參見配置檔案)通路我們的資産服務了,如http://localhost:8000/asset/list,如果沒有出現404錯誤,則說明将8081端口上的服務映射到了8000端口上,最後再通路eureka的服務(http://localhost:8761),可以清晰地看到我們有兩個eureka用戶端執行個體,如下圖所示:
4. HTTP代理服務
在項目的實際開發過程中,我們可能還需要內建其他語言版本的WEB應用程式,如python、nodejs,或者沒有采用eureka用戶端的服務,是以還可以直接配置HTTP代理,将配置檔案修改為如下内容:
zuul:
# 禁止服務自動添加
ignoredServices: '*'
# 手動添加服務
routes:
asset:
path: /asset/**
serviceId: ASSET
stripPrefix: false
users:
path: /users/**
url: http://localhost:/asset
asset:
ribbon:
listOfServers: localhost
現在不僅可以代理eureka伺服器的注冊服務,還可以代理其他HTTP服務,那麼內建nodejs、php、python的WEB服務也不成問題了。
結論
ZUUL伺服器可暫時了解為JAVA版的Nginx伺服器,支援各種路徑映射與代理,不僅支援eureka注冊的微服務,還支援非eureka版的JAVA WEB應用程式,最後還支援非JAVA語言版的WEB應用程式。