Gateway+Nacos动态路由

本文详细介绍了如何使用Spring Cloud Gateway和Nacos实现动态路由,包括配置依赖、yml设置、启动类编写、监听Nacos配置并更新路由,以及通过Controller接收请求的测试过程。重点展示了如何实现实时响应Nacos配置变化,确保服务路由的灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、pom依赖(关键部分)

1.gateway模块

		<!--引入gateway依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <!-- SpringCloud Alibaba Nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!-- SpringCloud Alibaba Nacos Config -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

2.test模块

		<!-- SpringCloud Alibaba Nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!-- SpringCloud Alibaba Nacos Config -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

二、配置yml

1.gateway模块

server:
  port: 7002

shine:
  dynamic:
    route:
      address: ${spring.cloud.nacos.config.server-addr}
      dataId: ${spring.application.name}
      groupId: SHINE_GROUP

spring:
  application:
    name: shine-gateway
  profiles:
    # 环境配置
    active: dev
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      url: jdbc:mysql://127.0.0.1:3306/数据库名称?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
      username: 用户名
      password: 密码
      # 初始连接数
      initialSize: 5
      # 最小连接池数量
      minIdle: 10
      # 最大连接池数量
      maxActive: 20
      # 配置获取连接等待超时的时间
      maxWait: 60000
      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # 配置一个连接在池中最小生存的时间,单位是毫秒
      minEvictableIdleTimeMillis: 300000
      # 配置一个连接在池中最大生存的时间,单位是毫秒
      maxEvictableIdleTimeMillis: 900000
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 127.0.0.1:7001
      config:
        # 配置中心地址
        server-addr: 127.0.0.1:7001
        # 配置文件格式
        file-extension: yml
        # 共享配置
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
    gateway:
      discovery:
        locator:
          # 服务名小写
          lower-case-service-id: true

# MyBatis配置
mybatis:
  # 加载全局的配置文件
  configLocation: classpath:mybatis/mybatis-config.xml
  # 配置mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/*Mapper.xml

2.test模块

server:
  port: 7003

spring:
  application:
    name: shine-client
  profiles:
    # 环境配置
    active: dev
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 127.0.0.1:7001
      config:
        # 配置中心地址
        server-addr: 127.0.0.1:7001
        # 配置文件格式
        file-extension: yml
        # 共享配置
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

三、编写启动类

1.gateway启动类

/**
 * @author ShineQianMo
 */
@SpringBootApplication
@EnableDiscoveryClient
public class ShineGatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(ShineGatewayApplication.class, args);
        System.out.println("Shine: shine-gateway模块启动成功");
    }

}

2.test启动类

/**
 * @author ShineQianMo
 */
@SpringBootApplication
@EnableDiscoveryClient
public class ShineClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(ShineClientApplication.class, args);
        System.out.println("Shine: shine-client模块启动成功");
    }
    
}

四、业务逻辑

1.监听nacos配置

/**
 * @author ShineQianMo
 * DateTime 2021/8/17 16:09
 */
@Configuration
public class DynamicRouteConfiguration {

    private static final Logger log = LoggerFactory.getLogger(DynamicRouteConfiguration.class);

    @Autowired
    private DynamicRoute nacosDynamicRoute;

    @Autowired
    private GatewayRouteService gatewayRouteService;

    @PostConstruct
    private void init() {
        dynamicRouteByNacosListener(nacosDynamicRoute.getDataId(), nacosDynamicRoute.getGroupId(), nacosDynamicRoute.getAddress());
    }

	// dataId、groupId、address 自己定义, address就是nacos地址+端口,我这里这三个值分别是shine-gateway、SHINE_GROUP、127.0.0.1:7001 我是从yml里加载的这边你们随意
    private void dynamicRouteByNacosListener(String dataId, String groupId, String address) {
        try {
            ConfigService configService = NacosFactory.createConfigService(address);
            configService.addListener(dataId, groupId, new Listener() {
                @Override
                public Executor getExecutor() {
                    return null;
                }

                @Override
                public void receiveConfigInfo(String configInfo) {
                    log.warn("监听到新的路由配置,正在更新中、、、");
                    List<RouteDefinition> routeDefinitionList = JSON.parseArray(configInfo, RouteDefinition.class);
                    for (RouteDefinition routeDefinition : routeDefinitionList) {
                        gatewayRouteService.addGatewayRoute(routeDefinition);
                    }
                    log.warn("路由更新完成");
                }
            });
        } catch (NacosException e) {
            e.printStackTrace();
            // 通知路由负责人(邮件)
        }
    }

}

2.路由更新

/**
 * @author ShineQianMo
 * DateTime 2021/8/17 10:57
 */
@Service
public class GatewayRouteServiceImpl implements GatewayRouteService, ApplicationEventPublisherAware {

    private static final Logger log = LoggerFactory.getLogger(GatewayRouteServiceImpl.class);

    private ApplicationEventPublisher publisher;

    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;

    @Override
    public List<GatewayRoute> getGatewayRouteList(GatewayRoute gatewayRoute) {
        return gatewayRouteMapper.selectGatewayRouteList(gatewayRoute);
    }

    @Override
    public int addGatewayRoute(RouteDefinition routeDefinition) {
        this.loadingOneRouteDefinition(routeDefinition);
        return 1;
    }
    
	@Override
    public void loadingOneRouteDefinition(RouteDefinition routeDefinition) {
        log.info("加载路由");
        // 先删除重名路由
        routeDefinitionWriter.delete(Mono.just(routeDefinition.getId()));
        // 再添加路由
        routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
        this.publisher.publishEvent(new RefreshRoutesEvent(this));
    }
}

test模块编写Controller接收请求


/**
 * @author ShineQianMo
 * DateTime 2021/8/17 19:30
 */
@RestController
public class a {

    @GetMapping("/a")
    public String a() {
        return "你好难打s";
    }
}

五、测试

1.启动nacos

2.启动gateway、test模块

3.编写nacos配置文件

我这里用的JSON格式的配置,java监听nacos也是直接转JSON

[
    {
        "id": "shine-client", 
        "order": 0, 
        "uri": "lb://shine-client", 
        "predicates": [
            {
                "name": "Path",
                "args": {
                    "_genkey_0": "/client/**"
                }
            }
        ], 
        "filters": [
            {
                "name": "StripPrefix",
                "args": {
                    "_genkey_0": "1"
                }
            }
        ]
    }
]

这个JSON改为yml:

spring:
  cloud:
    nacos:
      routes:
		- id: shine-client
          uri: lb://shine-client
          predicates:
            - Path=/client/**
          filters:
            - StripPrefix=1

发布nacos配置,可以看到java监听到nacos并加载了新的路由。
在这里插入图片描述

4.结果

7003请求正常通过
在这里插入图片描述
然后测试路由转发7002
在这里插入图片描述
完成,期间nacos遇到一些问题,还有gateway也有问题,后续将放到其他文章。

### 实现微服务架构与API管理 #### 1. 创建Spring Boot项目并引入依赖项 为了创建一个基于Spring Boot的微服务平台,首先需要初始化一个新的Spring Boot应用程序。此过程可以通过Spring Initializr完成,选择所需的依赖项如`Spring Web`, `Spring Cloud Gateway`, 和 `Spring Cloud Alibaba Nacos Discovery`. 对于Maven构建工具,在项目的根目录下的`pom.xml`文件中添加必要的依赖: ```xml <dependencies> <!-- Spring Boot Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring Cloud Gateway --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!-- Nacos Service Discovery --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-nacos-discovery</artifactId> </dependency> <!-- Swagger for API documentation --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>3.0.0</version> </dependency> </dependencies> ``` #### 2. 启动类配置 确保启动类上标注有`@EnableDiscoveryClient`以便于自动注册到Nacos服务中心。 ```java package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } ``` #### 3. 配置Nacos作为服务发现中心 编辑`application.properties`或`application.yml`来指定连接至本地或其他位置运行的服务端口以及地址信息: ```yaml server: port: 8761 spring: application: name: demo-service nacos: discovery: server-addr: localhost:8848 ``` #### 4. 使用Spring Cloud Gateway进行路由设置 通过定义自定义路径匹配器或者静态映射规则的方式来自由控制请求转发逻辑;可以在YAML配置文件里声明这些规则. ```yaml spring: cloud: gateway: routes: - id: example_route uri: lb://DEMO-SERVICE predicates: - Path=/example/** ``` 此处利用了负载均衡(`lb`)协议前缀指向目标服务名称,并设置了简单的路径谓词用于过滤符合条件的HTTP请求[^2]. #### 5. 整合Swagger UI以支持在线浏览API文档 为了让开发者能够更方便地测试接口功能,可以借助Swagger提供的UI界面展示所有已发布的RESTful APIs及其参数说明等内容。只需简单几步就能让应用具备这一特性——在主程序入口处加入相应Bean实例即可启用该插件的功能集。 ```java @Configuration @EnableSwagger2WebMvc public class SwaggerConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/swagger-ui.html") .addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/"); } @Bean Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.example.controller")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("Spring Boot RESTful APIs with Swagger") .description("This document describes the available services.") .termsOfServiceUrl("") .contact(new Contact("", "", "")) .license("") .licenseUrl("") .version("1.0") .build(); } } ``` 上述代码片段展示了如何配置Swagger的相关组件,包括但不限于资源处理器、Docket对象和基本信息描述等部分.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值