原創作者:老顧
轉載請註明出處
前言
當我們的網關Gateway程序開發完成之後,需要部署到生產環境,這個時候你的程序不能是單點運行的,肯定是多節點啓動(獨立部署或者docker等容器部署),防止單節點故障導致整個服務不能訪問,網關是對客戶端的入口與出口,在生產運行中極爲重要,哪怕是簡單的重啓也會導致部分請求的丟失。
網關的路由配置這個時候就是一個大問題,是代碼裏面編寫還是配置文件配置?他們都有一個致命的缺點,當有新的程序需要接入到網關進行路由或者有服務需要下線時候需要修改代碼或者配置,然後重啓整個網關程序,導致其他正常的服務路由受到了影響。
所以在實際生產環境中爲了保證高可靠和高可用,是儘量要避免重啓網關,所以實現動態路由是非常有必要的;
本文主要介紹Spring Cloud Gateway 實現的思路,並且把路由信息存放在外部源中,這裏以Nacos爲數據源來講解。
實現要點
要實現動態路由只需關注下面4個點
- 網關啓動時,動態路由的數據怎樣加載進來
- 靜態路由與動態路由以那個爲準
- 監聽動態路由的數據源變化
- 數據有變化時怎樣通知gateway刷新路由
ps:靜態路由指的是配置文件裏寫死的路由配置
具體實現
Spring Cloud Gateway 中加載路由信息分別由以下幾個類負責:
- PropertiesRouteDefinitionLocator:從配置文件中讀取路由信息(如YML、Properties等)
- RouteDefinitionRepository:從存儲器中讀取路由信息(如內存、配置中心、Redis、MySQL等)
- DiscoveryClientRouteDefinitionLocator:從註冊中心中讀取路由信息(如Nacos、Eurka、Zookeeper等)
我們可以通過自定義RouteDefinitionRepository的實現類來實現動態路由的目的。
實現動態路
有的數據加載我們可以查看源碼RouteDefinitionRepository的存儲的實現類,只有InMemoryRouteDefinitionRepository,此實現類是存放在內存中的。
我們可以重新定義一個nacos作爲存儲的實現,看下面的代碼
上面代碼核心的是重寫 getRouteDefinitions 方法實現路由信息的讀取;這個方法中涉及到了ConfigService對象Api的方法。
管理Api方法,這個老顧這裏不詳細說了;小夥伴們可以理解爲就是操作nacos config的對象
配置Nacos監聽器,監聽路由配置信息的變化,也是利用api方法,也就是addListener方法;此方法一看就知道,就是用來監聽config信息變化的。
此addListener方法中路由變化只需要往 ApplicationEventPublisher 推送一個 RefreshRoutesEvent 事件,即刻gateway會自動監聽該事件並調用 getRouteDefinitions 方法更新路由信息。
這樣就達到了動態更新路由了。
配置類
爲了更好的把此動態路由作爲公共core,我們需要利用配置類,達到是否啓用的方式;可以讓開發者自行配置。
上面的配置類,有兩個重要的@ConditionalOnProperty,這個就是用來控制是否啓用動態路由,以及是否用nacos作爲存儲。
裏面還有@Value註解定義我們存儲路由信息的DataId和Group,application.yml如果不配置默認值爲scg-routes和SCG_GATEWAY
添加Nacos路由配置
在同一個namespace中創建scg-routes和SCG_GATEWAY
格式選擇json,json體裏面的格式其實就是RouteDefinition類的屬性
注意上面的配置的json是數組格式哦,也就是可以有很多路由哦
[{
"id": "baidu",
"order": 0,
"predicates": [{
"args": {
"pattern": "/baidu/**"
}, "name": "Path"
}], "uri": "https://www.baidu.com"
},{ "id": "sina",
"order": 2,
"predicates": [{
"args": {
"pattern": "/sina/**"
}, "name": "Path"
}], "uri": "http://www.sina.com.cn"
}]
測試
在網關項目中的application.yml中配置
rainbow:
gateway:
dynamicRoute:
enabled: true
啓動網關,就可以了;爲了方便看到網關當前的路由信息,我們需要引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
並且在application.yml中配置
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
gateway:
enabled: true
health:
show-details: always
這樣我們就可以訪問http://localhost:8081/actuator/gateway/routes,就可以看到路由信息
小夥伴們可以嘗試修改一下nacos中的dataId爲scg-routes,我們可以發現路由及時 得到了更改。
老顧只修改了route_id的名稱,路由就及時更新了
我們也看到了控制檯日誌也有相應的變化
總結
gateway的動態路由是非常實用的功能,在生產環境中是必備功能,小夥伴們一定要掌握哦,當然小夥伴們也可以用其他的數據源。謝謝!!!