使用Nacos實(shí)現(xiàn)Spring Cloud Gateway動(dòng)態(tài)路由的詳細(xì)指南

2024-12-27 14:08 更新

Hello,大家好,我是 V 哥。最近寫到 使用 Nacos 實(shí)現(xiàn)動(dòng)態(tài)路由的問題,整理了一下思路和案例,分享給大家。

使用 Nacos 實(shí)現(xiàn) Spring Cloud Gateway 的動(dòng)態(tài)路由,主要涉及到以下幾個(gè)步驟:

  1. 添加依賴:在 Spring Cloud Gateway 應(yīng)用的 pom.xml 文件中添加 Nacos 相關(guān)依賴。

  1. 配置 Nacos:在 application.ymlapplication.properties 文件中配置 Nacos 服務(wù)地址。

  1. 啟用動(dòng)態(tài)路由:在配置文件中啟用 Nacos 動(dòng)態(tài)路由功能。

  1. 創(chuàng)建動(dòng)態(tài)路由配置:在 Nacos 配置中心創(chuàng)建動(dòng)態(tài)路由的配置信息。

  1. 監(jiān)聽配置變化:在 Spring Cloud Gateway 應(yīng)用中監(jiān)聽 Nacos 配置變化,動(dòng)態(tài)更新路由規(guī)則。

下面是具體的實(shí)現(xiàn)步驟和代碼案例,來看一下:

1. 添加依賴

pom.xml 文件中添加 Spring Cloud Gateway 和 Nacos 相關(guān)依賴:

  1. <dependencies>
  2. <!-- Spring Cloud Gateway -->
  3. <dependency>
  4. <groupId>org.springframework.cloud</groupId>
  5. <artifactId>spring-cloud-starter-gateway</artifactId>
  6. </dependency>
  7. <!-- Spring Cloud Alibaba Nacos Discovery -->
  8. <dependency>
  9. <groupId>com.alibaba.cloud</groupId>
  10. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  11. </dependency>
  12. <!-- Spring Cloud Alibaba Nacos Config -->
  13. <dependency>
  14. <groupId>com.alibaba.cloud</groupId>
  15. <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
  16. </dependency>
  17. </dependencies>

2. 配置 Nacos

application.yml 文件中配置 Nacos 服務(wù)地址:

  1. spring:
  2. cloud:
  3. nacos:
  4. discovery:
  5. server-addr: 127.0.0.1:8848 # Nacos 服務(wù)地址
  6. config:
  7. server-addr: 127.0.0.1:8848 # Nacos 配置中心地址
  8. file-extension: yml # 配置文件格式
  9. group: DEFAULT_GROUP # 配置分組
  10. namespace: # 配置命名空間

3. 啟用動(dòng)態(tài)路由

application.yml 文件中啟用 Nacos 動(dòng)態(tài)路由功能:

  1. spring:
  2. cloud:
  3. gateway:
  4. discovery:
  5. locator:
  6. enabled: true # 開啟從注冊中心動(dòng)態(tài)創(chuàng)建路由的功能
  7. lower-case-service-id: true # 使用小寫服務(wù)名,默認(rèn)是大寫

4. 創(chuàng)建動(dòng)態(tài)路由配置

在 Nacos 配置中心創(chuàng)建一個(gè)配置文件,例如 gateway-routes.yml,內(nèi)容如下:

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: my-service-route
  6. uri: lb://MY-SERVICE
  7. predicates:
  8. - Path=/my-service/**
  9. filters:
  10. - StripPrefix=1

5. 監(jiān)聽配置變化

在 Spring Cloud Gateway 應(yīng)用中,創(chuàng)建一個(gè)配置類來監(jiān)聽 Nacos 配置變化,并刷新路由規(guī)則:

  1. import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
  2. import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
  3. import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
  4. import org.springframework.context.event.EventListener;
  5. import org.springframework.stereotype.Component;
  6. @Component
  7. public class DynamicRouteService {
  8. private final RouteDefinitionWriter routeDefinitionWriter;
  9. private final RouteDefinitionLocator routeDefinitionLocator;
  10. public DynamicRouteService(RouteDefinitionWriter routeDefinitionWriter,
  11. RouteDefinitionLocator routeDefinitionLocator) {
  12. this.routeDefinitionWriter = routeDefinitionWriter;
  13. this.routeDefinitionLocator = routeDefinitionLocator;
  14. }
  15. @EventListener
  16. public void onEnvironmentChange(EnvironmentChangeEvent event) {
  17. if (event.getKeys().contains("spring.cloud.gateway.routes")) {
  18. routeDefinitionLocator.getRouteDefinitions()
  19. .subscribe(routeDefinitions -> {
  20. routeDefinitionWriter.delete("*").subscribe();
  21. routeDefinitionWriter.save(routeDefinitions).subscribe();
  22. });
  23. }
  24. }
  25. }

這個(gè)類會(huì)監(jiān)聽環(huán)境變化事件,當(dāng)檢測到 spring.cloud.gateway.routes 配置項(xiàng)發(fā)生變化時(shí),會(huì)重新加載和刷新路由規(guī)則。

我們通過使用 Nacos 實(shí)現(xiàn) Spring Cloud Gateway 的動(dòng)態(tài)路由。通過在 Nacos 配置中心維護(hù)路由配置,可以實(shí)現(xiàn)不重啟網(wǎng)關(guān)服務(wù)的情況下動(dòng)態(tài)更新路由規(guī)則,這對于微服務(wù)架構(gòu)中的服務(wù)治理非常有用。

在使用 Nacos 動(dòng)態(tài)路由時(shí),如果服務(wù)下線了,Spring Cloud Gateway 會(huì)如何響應(yīng)?

當(dāng)使用 Nacos 動(dòng)態(tài)路由時(shí),如果服務(wù)下線,Spring Cloud Gateway 會(huì)通過 Nacos 的服務(wù)發(fā)現(xiàn)機(jī)制感知到這一變化,并根據(jù)配置的動(dòng)態(tài)路由規(guī)則進(jìn)行調(diào)整。如何配置 Spring Cloud Gateway 以響應(yīng)服務(wù)下線的情況呢?來,上代碼:

首先,確保咱們的項(xiàng)目中已經(jīng)添加了 Spring Cloud Gateway 和 Spring Cloud Alibaba Nacos Discovery 的依賴。

1. application.yml 配置

application.yml 中配置 Nacos 服務(wù)發(fā)現(xiàn)和動(dòng)態(tài)路由:

  1. spring:
  2. cloud:
  3. nacos:
  4. discovery:
  5. server-addr: 127.0.0.1:8848 # Nacos 服務(wù)地址
  6. gateway:
  7. routes:
  8. - id: my-service-route
  9. uri: lb://MY-SERVICE
  10. predicates:
  11. - Path=/my-service/**
  12. filters:
  13. - StripPrefix=1
  14. discovery:
  15. locator:
  16. enabled: true
  17. lower-case-service-id: true

2. Nacos 配置中心的動(dòng)態(tài)路由配置

在 Nacos 配置中心創(chuàng)建一個(gè)名為 gateway-routes.json 的配置文件,內(nèi)容如下:

  1. {
  2. "spring": {
  3. "cloud": {
  4. "gateway": {
  5. "routes": [
  6. {
  7. "id": "my-service-route",
  8. "uri": "lb://MY-SERVICE",
  9. "predicates": [
  10. {
  11. "name": "Path",
  12. "args": {
  13. "_genkey_0": "/my-service/**"
  14. }
  15. }
  16. ],
  17. "filters": [
  18. {
  19. "name": "StripPrefix",
  20. "args": {
  21. "_genkey_1": "1"
  22. }
  23. }
  24. ]
  25. }
  26. ]
  27. }
  28. }
  29. }
  30. }

3. 動(dòng)態(tài)路由配置監(jiān)聽

創(chuàng)建一個(gè)配置類來監(jiān)聽 Nacos 配置變化,并刷新路由規(guī)則:

  1. import com.alibaba.cloud.nacos.NacosConfigManager;
  2. import com.alibaba.cloud.nacos.NacosConfigProperties;
  3. import com.alibaba.nacos.api.NacosFactory;
  4. import com.alibaba.nacos.api.config.ConfigService;
  5. import com.alibaba.nacos.api.exception.NacosException;
  6. import com.alibaba.nacos.api.model.Properties;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.boot.ApplicationArguments;
  9. import org.springframework.boot.ApplicationRunner;
  10. import org.springframework.cloud.gateway.route.RouteDefinition;
  11. import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
  12. import org.springframework.cloud.gateway.route.RoutesRefreshedEvent;
  13. import org.springframework.context.ApplicationEventPublisher;
  14. import org.springframework.stereotype.Component;
  15. import java.util.Properties as JavaProperties;
  16. @Component
  17. public class NacosDynamicRoute implements ApplicationRunner {
  18. @Autowired
  19. private RouteDefinitionRepository routeDefinitionRepository;
  20. @Autowired
  21. private ApplicationEventPublisher publisher;
  22. private ConfigService configService;
  23. public NacosDynamicRoute(NacosConfigProperties properties) throws NacosException {
  24. JavaProperties javaProperties = new JavaProperties();
  25. javaProperties.setProperty("serverAddr", properties.getServerAddr());
  26. javaProperties.setProperty("namespace", properties.getNamespace());
  27. configService = NacosFactory.createConfigService(javaProperties);
  28. }
  29. @Override
  30. public void run(ApplicationArguments args) {
  31. try {
  32. String routeJson = configService.getConfig("gateway-routes.json", "DEFAULT_GROUP", 5000);
  33. refreshRoutes(routeJson);
  34. configService.addListener("gateway-routes.json", "DEFAULT_GROUP", s -> refreshRoutes(s));
  35. } catch (NacosException e) {
  36. e.printStackTrace();
  37. }
  38. }
  39. private void refreshRoutes(String routeJson) {
  40. SpringCloudRouteDefinition routeDefinition = JsonUtils.deserialize(routeJson, SpringCloudRouteDefinition.class);
  41. routeDefinitionRepository.delete("*").subscribe();
  42. routeDefinitionRepository.save(routeDefinition.getRouteDefinitions()).subscribe();
  43. publisher.publishEvent(new RoutesRefreshedEvent(this));
  44. }
  45. // 內(nèi)部類,用于反序列化 Nacos 配置
  46. static class SpringCloudRouteDefinition {
  47. private RouteDefinition[] routeDefinitions;
  48. // getter 和 setter 省略
  49. }
  50. }

NacosDynamicRoute 類會(huì)在應(yīng)用啟動(dòng)時(shí)從 Nacos 配置中心加載路由配置,并注冊一個(gè)監(jiān)聽器來監(jiān)聽配置變化。當(dāng)配置發(fā)生變化時(shí),它會(huì)重新加載路由配置并刷新路由規(guī)則。點(diǎn)贊+關(guān)注,學(xué)習(xí) Java 不迷路。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號