跟我學SpringCloud | 第十七篇:服務網關Zuul基於Apollo動態路由


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格式的配置:

  1. application (應用)
  2. environment (環境)
  3. cluster (集群)
  4. 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

  1. 工程依賴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>
  1. 配置文件

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中,具體如圖:

  1. 啟動主類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配置。

  1. 路由刷新

代碼路徑: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()刷新路由信息。

  1. 測試

我們啟動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-示例代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM