跟我學SpringCloud | 第十七篇:服務閘道器Zuul基於Apollo動態路由
目錄
- SpringCloud系列教程 | 第十七篇:服務閘道器Zuul基於Apollo動態路由
- Apollo概述
- Apollo相比於Spring Cloud Config優勢
- 工程實戰
- 示例程式碼
SpringCloud系列教程 | 第十七篇:服務閘道器Zuul基於Apollo動態路由
Springboot: 2.1.7.RELEASE
SpringCloud: Greenwich.SR2
上一篇文章我們介紹了Gateway基於Nacos動態閘道器路由的解決方案《Spring Cloud Alibaba | Gateway基於Nacos動態閘道器路由》,同為Spring Cloud服務閘道器元件的Spring Cloud Zuul在生產環境中使用更為廣泛,那麼它有沒有方便的動態路由解決方案呢?答案當然是肯定的,Zuul作為一個老牌的開源服務閘道器元件,動態路由對它來講是一個十分必要的功能,畢竟我們不能隨便重啟服務閘道器,服務閘道器是一個微服務系統的大門,今天我們介紹的Zuul動態路由的解決方案來自於攜程開源的配置中心Apollo。
Apollo概述
Apollo(阿波羅)是攜程框架部門研發的開源配置管理中心,能夠集中化管理應用不同環境、不同叢集的配置,配置修改後能夠實時推送到應用端,並且具備規範的許可權、流程治理等特性。
Apollo支援4個維度管理Key-Value格式的配置:
- application (應用)
- environment (環境)
- cluster (叢集)
- namespace (名稱空間)
Apollo相比於Spring Cloud Config優勢
前面的文章我們也介紹了Spring Cloud Config《跟我學SpringCloud | 第七篇:Spring Cloud Config 配置中心高可用和refresh》,但是它和我們今天要使用的相比,又有什麼劣勢呢?
Spring Cloud Config的精妙之處在於它的配置儲存於Git,這就天然的把配置的修改、許可權、版本等問題隔離在外。通過這個設計使得Spring Cloud Config整體很簡單,不過也帶來了一些不便之處。
功能點 | Apollo | Spring Cloud Config | 備註 |
---|---|---|---|
配置介面 | 一個介面管理不同環境、不同叢集配置 | 無,需要通過git操作 | |
配置生效時間 | 實時 | 重啟生效,或手動refresh生效 | Spring Cloud Config需要通過Git webhook,加上額外的訊息佇列才能支援實時生效 |
版本管理 | 介面上直接提供釋出歷史和回滾按鈕 | 無,需要通過git操作 | |
灰度釋出 | 支援 | 不支援 | |
授權、稽核、審計 | 介面上直接支援,而且支援修改、釋出許可權分離 | 需要通過git倉庫設定,且不支援修改、釋出許可權分離 | |
例項配置監控 | 可以方便的看到當前哪些客戶端在使用哪些配置 | 不支援 | |
配置獲取效能 | 快,通過資料庫訪問,還有快取支援 | 較慢,需要從git clone repository,然後從檔案系統讀取 | |
客戶端支援 | 原生支援所有Java和.Net應用,提供API支援其它語言應用,同時也支援Spring annotation獲取配置 | 支援Spring應用,提供annotation獲取配置 | Apollo的適用範圍更廣一些 |
工程實戰
這裡需要準備一個Apollo配置中心,具體如何構建Apollo配置中心我這裡不多做介紹,大家可以參考Apollo的官方文件:https://github.com/ctripcorp/apollo/wiki
- 工程依賴pom.xml如下:
程式碼清單:chapter16/pom.xml
***
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>${apollo-client.version}</version>
</dependency>
<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>
- 配置檔案
app.properties如下:
程式碼清單:chapter16/src/main/resources/META-INF/app.properties
***
app.id=123456789
這裡配置的app.id
是在Apollo中建立專案時配置的。
application.yml如下:
程式碼清單:chapter16/src/main/resources/application.yml
***
apollo:
bootstrap:
enabled: true
namespaces: zuul-config-apollo
Meta: http://localhost:8080
在Apollo上新建一個名稱空間zuul-config-apollo
。
其餘的配置都配置在Apollo中,具體如圖:
- 啟動主類Chapter16Application.java如下:
程式碼清單:chapter16/src/main/java/com/springcloud/chapter16/Chapter16Application.java
***
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
@EnableApolloConfig
public class Chapter16Application {
public static void main(String[] args) {
SpringApplication.run(Chapter16Application.class, args);
}
}
其中@EnableZuulProxy
表示開啟Zuul閘道器代理,@EnableApolloConfig
表示開啟Apollo配置。
- 路由重新整理
程式碼路徑:chapter16/src/main/java/com/springcloud/chapter16/config/ZuulProxyRefresher.java
***
@Component
public class ZuulProxyRefresher implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Autowired
private RouteLocator routeLocator;
@ApolloConfigChangeListener(value = "zuul-config-apollo")
public void onChange(ConfigChangeEvent changeEvent) {
boolean zuulProxyChanged = false;
for (String changedKey : changeEvent.changedKeys()) {
if (changedKey.startsWith("zuul.")) {
zuulProxyChanged = true;
break;
}
}
if (zuulProxyChanged) {
refreshZuulProxy(changeEvent);
}
}
private void refreshZuulProxy(ConfigChangeEvent changeEvent) {
this.applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
this.applicationContext.publishEvent(new RoutesRefreshedEvent(routeLocator));
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
@ApolloConfigChangeListener(value = "zuul-config-apollo")
中value的預設引數是application
,因為這裡我們自定義了namespace,所以需要指定,我們使用@ApolloConfigChangeListener
監聽Apollo的配置下發,有配置更新時會呼叫refreshZuulProxy()
重新整理路由資訊。
- 測試
我們啟動Client-Apollo工程和Zuul-Apollo工程,開啟瀏覽器訪問:http://localhost:9091/client/hello ,頁面可以正常顯示,我們在Apollo中修改路由資訊,具體如圖:
修改完後點擊發布,待發布成功後,我們重新整理瀏覽器,之前的路由訪問已經報錯404,我們使用修改過後的路由http://localhost:9091/client_new/hello ,頁面可以正常顯示Hello, i am dev from apollo update.
,測試成功,我們通過Apollo實現了Zuul的路由資訊動態重新整理。
示例程式碼
Github-示例程式碼
Gitee-示例