言三 發表於 2026-1-8 17:09:50

SpringCloud Gateway的使用 + Nacos动态路由实践指南

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>一、简介</li><ul class="second_class_ul"><li>1、什么是gateway?</li><li>2、没有gateway的弊端</li><li>3、gateway解决了什么?</li><li>4、gateway和zuul的区别</li><li>5、gateway核心概念</li><li>6、gateway是如何工作的</li></ul><li>二、构建一个springcloud Gateway服务</li><ul class="second_class_ul"><li>1、新建一个微服务</li><ul class="third_class_ul"><li>1.1、新建gateway子模块</li><li>1.2、引入依赖</li></ul><li>2、配置服务</li><ul class="third_class_ul"><li>2.1、创建启动类</li><li>2.2、创建application.yml配置文件</li><li>2.3、启动并访问Gateway服务</li><li>2.4、通过微服务名称的方式来路由服务</li><li>2.5、路由websocket服务</li><li>2.6、测试负载均衡</li></ul></ul><li>三、通过nacos实现动态路由</li><ul class="second_class_ul"></ul></ul></div><p class="maodian"></p><h2>一、简介</h2>
<p class="maodian"></p><h3>1、什么是gateway?</h3>
<ul><li>SpringCloud Gateway是spring官方基于Spring 5.0、Spring Boot2.0和Project Reactor等技术开发的网关,旨在为微服务架构提供简单、有效和统一的API路由管理方式</li><li>SpringCloud Gateway作为SpringCloud生态系统中的网关,目标是替代Netflix Zuul,在SpringCloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新高性能版本进行集成,仍然还是使用Zuul 1.x非Reactor模式的老版本。二为了提高网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty</li><li>SpringCloud Gateway不仅提供统一的路由方式,并且还基于Filer链的方式提供了网关基本的功能,例如:鉴权、监控/指标、流量控制、熔断限流等</li></ul>
<p class="maodian"></p><h3>2、没有gateway的弊端</h3>
<ul><li>客户端多次请求不同的微服务,会增加客户端代码和配置的复杂性,维护成本比价高</li><li>认证复杂,每个微服务可能存在不同的认证方式,客户端去调用,要去适配不同的认证</li><li>存在跨域的请求,调用链有一定的相对复杂性(防火墙 / 浏览器不友好的协议)</li><li>难以重构,随着项目的迭代,可能需要重新划分微服务</li></ul>
<p class="maodian"></p><h3>3、gateway解决了什么?</h3>
<p>为了解决上面的问题,微服务引入了 网关 的概念,网关为微服务架构的系统提供简单、有效且统一的API路由管理,作为系统的统一入口,提供内部服务的路由中转,给客户端提供统一的服务,可以实现一些和业务没有耦合的公用逻辑,主要功能包含认证、鉴权、路由转发、安全策略、防刷、流量控制、监控日志等</p>
<p class="maodian"></p><h3>4、gateway和zuul的区别</h3>
<ul><li>Zuul构建于 Servlet 2.5,兼容 3.x,使用的是阻塞式的 API,不支持长连接,比如 websockets</li><li>Spring Cloud Gateway构建于 Spring 5+,基于 Spring Boot 2.x 响应式的、非阻塞式的 API。同时,它支持 websockets,和 Spring 框架紧密集成,开发体验相对来说十分不错</li></ul>
<p class="maodian"></p><h3>5、gateway核心概念</h3>
<ul><li>Route(路由): 路由是网关最基础的部分,路由信息有一个ID、一个目的URL、一组断言和一组Filter组成。如果断言路由为真,则说明请求的URL和配置匹配</li><li>Predicate(断言): 参考的是java8的java.util.function.Predicate,开发人员可以匹配Http请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由</li><li>Filter(过滤器): 一个标准的Spring webFilter。SpringCloud Gateway中的Filter分为两种类型的Filter,分别是Gateway Filter和Global Filter。使用过滤器,可以在请求被路由前或者之后对请求进行修改</li></ul>
<p class="maodian"></p><h3>6、gateway是如何工作的</h3>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010817015491.png" /></p>
<p>官方解释:</p>
<blockquote><p>客户端SpringCloud Gateway发出请求,然后在Gateway Handler Mapping中找到与之请求相匹配的路由,将其发送到Gateway Web Handler,Handler再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。<br />过滤器之间用虚线分开是因为过滤器可能会发在代理请求之前(&ldquo;pre&rdquo;)或之后(&ldquo;post&rdquo;)执行业务逻辑,这样,Filter在&ldquo;pre&rdquo;类型的过滤器可以做参数校验,权限校验,流量监控,日志输出,协议转换等;在&ldquo;post&rdquo;类型的过滤器可以做响应内容,响应头的修改,日志的输出,流量监控等有着非常重要的作用</p></blockquote>
<p class="maodian"></p><h2>二、构建一个springcloud Gateway服务</h2>
<p class="maodian"></p><h3>1、新建一个微服务</h3>
<p class="maodian"></p><h4>1.1、新建gateway子模块</h4>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010817015498.png" /></p>
<p>nacos注册中心和配置中心以及服务服搭建可以参考之前的文章,这里基于之前的项目构建gateway服务</p>
<p>SpringCloud&nbsp;Alibaba微服务实战之远程Feign请求头丢失问题解决方案</p>
<p class="maodian"></p><h4>1.2、引入依赖</h4>
<p>gateway服务依赖</p>
<div class="jb51code"><pre class="brush:plain;">&lt;dependencies&gt;
      &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
            &lt;artifactId&gt;spring-cloud-starter-gateway&lt;/artifactId&gt;
            &lt;version&gt;3.0.7&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
            &lt;groupId&gt;com.mdx&lt;/groupId&gt;
            &lt;artifactId&gt;mdx-shop-common&lt;/artifactId&gt;
            &lt;version&gt;1.0.0&lt;/version&gt;
      &lt;/dependency&gt;
    &lt;/dependencies&gt;</pre></div>
<p>下面是全局的关于springcloud的依赖<br />spring-cloud.version:2021.0.1<br />spring-cloud-alibaba.version: 2021.0.1.0</p>
<div class="jb51code"><pre class="brush:plain;">&lt;dependency&gt;
            &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
            &lt;artifactId&gt;spring-cloud-dependencies&lt;/artifactId&gt;
            &lt;version&gt;${spring-cloud.version}&lt;/version&gt;
            &lt;type&gt;pom&lt;/type&gt;
            &lt;scope&gt;import&lt;/scope&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
            &lt;groupId&gt;com.alibaba.cloud&lt;/groupId&gt;
            &lt;artifactId&gt;spring-cloud-alibaba-dependencies&lt;/artifactId&gt;
            &lt;version&gt;${spring-cloud-alibaba.version}&lt;/version&gt;
            &lt;type&gt;pom&lt;/type&gt;
            &lt;scope&gt;import&lt;/scope&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
            &lt;groupId&gt;com.alibaba.cloud&lt;/groupId&gt;
            &lt;artifactId&gt;spring-cloud-starter-alibaba-nacos-discovery&lt;/artifactId&gt;
            &lt;version&gt;${spring-cloud-alibaba.version}&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
            &lt;groupId&gt;com.alibaba.cloud&lt;/groupId&gt;
            &lt;artifactId&gt;spring-cloud-starter-alibaba-nacos-config&lt;/artifactId&gt;
            &lt;version&gt;${spring-cloud-alibaba.version}&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
            &lt;artifactId&gt;spring-cloud-starter-bootstrap&lt;/artifactId&gt;
            &lt;version&gt;3.0.2&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
            &lt;artifactId&gt;spring-cloud-starter-openfeign&lt;/artifactId&gt;
            &lt;version&gt;3.1.1&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
            &lt;artifactId&gt;spring-cloud-loadbalancer&lt;/artifactId&gt;
            &lt;version&gt;3.1.1&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
            &lt;groupId&gt;com.alibaba.cloud&lt;/groupId&gt;
            &lt;artifactId&gt;spring-cloud-starter-alibaba-sentinel&lt;/artifactId&gt;
            &lt;version&gt;${spring-cloud-alibaba.version}&lt;/version&gt;
      &lt;/dependency&gt;</pre></div>
<p class="maodian"></p><h3>2、配置服务</h3>
<p class="maodian"></p><h4>2.1、创建启动类</h4>
<div class="jb51code"><pre class="brush:java;">@SpringBootApplication
@EnableFeignClients
public class MdxShopGateWayApplication {
    public static void main(String[] args) {
      SpringApplication.run(MdxShopGateWayApplication.class, args);
    }
}
</pre></div>
<p class="maodian"></p><h4>2.2、创建application.yml配置文件</h4>
<p>使用ip路由的方式:</p>
<div class="jb51code"><pre class="brush:plain;">server:
port: 9010
spring:
application:
    name: mdx-shop-gateway
cloud:
    nacos:
      discovery:
      server-addr: localhost:8848
      namespace: mdx
      group: mdx
    gateway:
      routes:
      - id: mdx-shop-user             #路由的ID,没有固定规则但要求唯一,建议配合服务名
          uri: http://localhost:9090    #匹配后提供服务的路由地址
          predicates:
            - Path=/user/**    #断言,路径相匹配的进行路由
      - id: mdx-shop-order
          uri: http://localhost:9091
          predicates:
            - Path=/order/**</pre></div>
<p class="maodian"></p><h4>2.3、启动并访问Gateway服务</h4>
<p>发现报错了&hellip;<br />大致意思是在springboot整合gateway时, gateway组件中的 【spring-boot-starter-webflux】 和 springboot作为web项目启动必不可少的 【spring-boot-starter-web】 出现冲突</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010817015422.png" /></p>
<p>我们按照提示: Please set spring.main.web-application-type=reactive or remove spring-boot-starter-web dependency.<br />在配置文件配置下 spring.main.web-application-type=reactive 就好了</p>
<div class="jb51code"><pre class="brush:plain;">main:
    web-application-type: reactive</pre></div>
<p>接着在重新启动项目,成功启动</p>
<p>然后我们再依次启动order服务和user服务</p>
<p>通过gateway访问user服务:<br />http://localhost:9010/user/getOrderNo?userId=mdx123456<br />其中9010端口为网关服务</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010817015475.png" /></p>
<p>通过gateway访问order服务:<br />http://localhost:9010/order/getOrderNo?userId=mdx123456<br />其中9010端口为网关服务</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010817015410.png" /></p>
<p>可见以上gateway均已成功路由到两个服务</p>
<p class="maodian"></p><h4>2.4、通过微服务名称的方式来路由服务</h4>
<p>把 gateway配置文件中的 uri: http://localhost:9090 改为 uri: lb://mdx-shop-user 这种服务名的形式</p>
<div class="jb51code"><pre class="brush:plain;">server:
port: 9010
spring:
application:
    name: mdx-shop-gateway
cloud:
    nacos:
      discovery:
      server-addr: localhost:8848
      namespace: mdx
      group: mdx
    gateway:
      routes:
      - id: mdx-shop-user             #路由的ID,没有固定规则但要求唯一,建议配合服务名
          uri: lb://mdx-shop-user    #匹配后提供服务的路由地址
          predicates:
            - Path=/user/**      #断言,路径相匹配的进行路由
      - id: mdx-shop-order
          uri: lb://mdx-shop-order
          predicates:
            - Path=/order/**
main:
    web-application-type: reactive</pre></div>
<p>再来测试一下user服务<br />http://localhost:9010/user/getOrderNo?userId=mdx123456<br />其中9010端口为网关服务</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010817015413.png" /></p>
<p>成功返回</p>
<p class="maodian"></p><h4>2.5、路由websocket服务</h4>
<p>将 uri: lb://mdx-shop-user 改为 uri: lb:ws://mdx-shop-user</p>
<div class="jb51code"><pre class="brush:plain;">routes:
      - id: mdx-shop-user             #路由的ID,没有固定规则但要求唯一,建议配合服务名
          uri: lb:ws://mdx-shop-user    #匹配后提供服务的路由地址
          predicates:
            - Path=/user/**      #断言,路径相匹配的进行路由</pre></div>
<p class="maodian"></p><h4>2.6、测试负载均衡</h4>
<p>采用这种路由方式 uri: lb://mdx-shop-user<br />在gateway添加配置:<br />开启通过服务中心的自动根据 serviceId 创建路由的功能</p>
<div class="jb51code"><pre class="brush:plain;">gateway:
      discovery:
      locator:
          enabled: true</pre></div>
<p>我们在order服务中写一个测试类,如下</p>
<div class="jb51code"><pre class="brush:java;">/**
   * 测试负载均衡
   * @return
   */
    @GetMapping("lb")
    public String lb(){
      System.out.println("test lb");
      return "lb";
    }</pre></div>
<p>分别启动两个order服务(启动一个order服务之后,修改下端口号再启动一个)</p>
<p>在idea中启动同一个服务的多个端口操作如下:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010817015667.png" /></p>
<p>成功启动了两个order服务</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010817015489.png" /></p>
<p>nacos状态如下(启动了两个实例)</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010817015674.png" /></p>
<p>我们再来通过网关访问下order服务<br />http://localhost:9010/order/lb<br />其中 9010 为网关端口<br />首先访问一次<br />我们看到order1服务打印了日志,order2服务没有日志</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010817015646.png" /></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010817015610.png" /></p>
<p>再访问一次接口<br />这个时候order2打印了日志,order1没有打印日志</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010817015649.png" /></p>
<p>如此实现了简单的负载均衡</p>
<p class="maodian"></p><h2>三、通过nacos实现动态路由</h2>
<blockquote><p>微服务都是互相独立的,假如我们的网关和其他服务都在线上已经运行了好久,这个时候增加了一个微服务,这个时候要通过网关访问的话需要通过修改配置文件来增加路由规则,并且需要重启项目,所以我们需要实现动态路由</p></blockquote>
<p><strong>1、创建路由配置接口</strong></p>
<p>新建路由发布接口</p>
<div class="jb51code"><pre class="brush:java;">/**
* 路由配置服务
* @author : jiagang
* @date : Created in 2022/7/20 11:07
*/
public interface RouteService {
    /**
   * 更新路由配置
   *
   * @param routeDefinition
   */
    void update(RouteDefinition routeDefinition);
    /**
   * 添加路由配置
   *
   * @param routeDefinition
   */
    void add(RouteDefinition routeDefinition);
}</pre></div>
<p>实现类如下</p>
<div class="jb51code"><pre class="brush:java;">package com.mdx.gateway.service.impl;
import com.mdx.gateway.service.RouteService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
/**
* @author : jiagang
* @date : Created in 2022/7/20 11:10
*/
@Service
@Slf4j
public class RouteServiceImpl implements RouteService, ApplicationEventPublisherAware {
    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;
    /**
   * 事件发布者
   */
    private ApplicationEventPublisher publisher;
    @Override
    public void update(RouteDefinition routeDefinition) {
      log.info("更新路由配置项:{}", routeDefinition);
      this.routeDefinitionWriter.delete(Mono.just(routeDefinition.getId()));
      routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
      this.publisher.publishEvent(new RefreshRoutesEvent(this));
    }
    @Override
    public void add(RouteDefinition routeDefinition) {
      log.info("新增路由配置项:{}", routeDefinition);
      routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
      this.publisher.publishEvent(new RefreshRoutesEvent(this));
    }
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
      this.publisher = applicationEventPublisher;
    }
}</pre></div>
<p>其中:<br />RouteDefinitionWriter:提供了对路由的增加删除等操作<br />ApplicationEventPublisher: 是ApplicationContext的父接口之一,他的功能就是发布事件,也就是把某个事件告诉所有与这个事件相关的监听器</p>
<p><strong>2、在nacos创建gateway-routes配置文件</strong></p>
<p>将路由信息放到nacos的配置文件下</p>
<p>新建配置文件,并将order服务的路由添加到配置文件</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010817015698.png" /></p>
<p>配置路由如下:</p>
<div class="jb51code"><pre class="brush:plain;">[
    {
      "predicates":[
            {
                "args":{
                  "pattern":"/order/**"
                },
                "name":"Path"
            }
      ],
      "id":"mdx-shop-order",
      "filters":[
            {
                "args":{
                  "parts":1
                },
                "name":"StripPrefix"
            }
      ],
      "uri":"lb://mdx-shop-order",
      "order":1
    }
]</pre></div>
<p>这个路由配置对应的就是gateway中的RouteDefinition类</p>
<p><strong>3、在本地配置文件下配置路由的data-id和group和命名空间</strong></p>
<div class="jb51code"><pre class="brush:plain;">gateway:
routes:
    config:
      data-id: gateway-routes#动态路由
      group: shop
      namespace: mdx</pre></div>
<p>完整配置文件(删除或者注释掉之前配置在本地文件的路由)</p>
<div class="jb51code"><pre class="brush:plain;">server:
port: 9010
spring:
application:
    name: mdx-shop-gateway
cloud:
    nacos:
      discovery:
      server-addr: localhost:8848
      namespace: mdx
      group: mdx
    gateway:
      discovery:
      locator:
          enabled: true#开启通过服务中心的自动根据 serviceId 创建路由的功能
main:
    web-application-type: reactive
gateway:
routes:
    config:
      data-id: gateway-routes#动态路由
      group: shop
      namespace: mdx</pre></div>
<p><strong>4、创建路由相关配置类</strong></p>
<p>创建配置类引入配置</p>
<div class="jb51code"><pre class="brush:java;">/**
* @author : jiagang
* @date : Created in 2022/7/20 14:44
*/
@ConfigurationProperties(prefix = "gateway.routes.config")
@Component
@Data
public class GatewayRouteConfigProperties {
    private String dataId;
    private String group;
        private String namespace;
}</pre></div>
<p><strong>5、实例化nacos的ConfigService,交由springbean管理</strong></p>
<blockquote><p>ConfigService 这个类是nacos的分布式配置接口,主要是用来获取配置和添加监听器</p></blockquote>
<p>由NacosFactory来创建ConfigService</p>
<div class="jb51code"><pre class="brush:java;">/**
* 将configService交由spring管理
* @author : jiagang
* @date : Created in 2022/7/20 15:27
*/
@Configuration
public class GatewayConfigServiceConfig {
    @Autowired
    private GatewayRouteConfigProperties configProperties;
    @Autowired
    private NacosConfigProperties nacosConfigProperties;
    @Bean
    public ConfigService configService() throws NacosException {
      Properties properties = new Properties();
      properties.setProperty(PropertyKeyConst.SERVER_ADDR, nacosConfigProperties.getServerAddr());
      properties.setProperty(PropertyKeyConst.NAMESPACE, configProperties.getNamespace());
      return NacosFactory.createConfigService(properties);
    }
}</pre></div>
<p><strong>6、动态路由主要实现</strong></p>
<p>项目启动时会加载这个类<br />@PostConstruc 注解的作用,在spring bean的生命周期依赖注入完成后被调用的方法</p>
<div class="jb51code"><pre class="brush:java;">package com.mdx.gateway.route;
import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mdx.common.utils.StringUtils;
import com.mdx.gateway.service.RouteService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executor;
/**
* @author : jiagang
* @date : Created in 2022/7/20 15:04
*/
@Component
@Slf4j
@RefreshScope
public class GatewayRouteInitConfig {
    @Autowired
    private GatewayRouteConfigProperties configProperties;
    @Autowired
    private NacosConfigProperties nacosConfigProperties;
    @Autowired
    private RouteService routeService;
    /**
   * nacos 配置服务
   */
    @Autowired
    private ConfigService configService;
    /**
   * JSON 转换对象
   */
    private final ObjectMapper objectMapper = new ObjectMapper();
    @PostConstruct
    public void init() {
      log.info("开始网关动态路由初始化...");
      try {
            // getConfigAndSignListener()方法 发起长轮询和对dataId数据变更注册监听的操作
            // getConfig 只是发送普通的HTTP请求
            String initConfigInfo = configService.getConfigAndSignListener(configProperties.getDataId(), configProperties.getGroup(), nacosConfigProperties.getTimeout(), new Listener() {
                @Override
                public Executor getExecutor() {
                  return null;
                }
                @Override
                public void receiveConfigInfo(String configInfo) {
                  if (StringUtils.isNotEmpty(configInfo)) {
                        log.info("接收到网关路由更新配置:\r\n{}", configInfo);
                        List&lt;RouteDefinition&gt; routeDefinitions = null;
                        try {
                            routeDefinitions = objectMapper.readValue(configInfo, new TypeReference&lt;List&lt;RouteDefinition&gt;&gt;() {
                            });
                        } catch (JsonProcessingException e) {
                            log.error("解析路由配置出错," + e.getMessage(), e);
                        }
                        for (RouteDefinition definition : Objects.requireNonNull(routeDefinitions)) {
                            routeService.update(definition);
                        }
                  } else {
                        log.warn("当前网关无动态路由相关配置");
                  }
                }
            });
            log.info("获取网关当前动态路由配置:\r\n{}", initConfigInfo);
            if (StringUtils.isNotEmpty(initConfigInfo)) {
                List&lt;RouteDefinition&gt; routeDefinitions = objectMapper.readValue(initConfigInfo, new TypeReference&lt;List&lt;RouteDefinition&gt;&gt;() {
                });
                for (RouteDefinition definition : routeDefinitions) {
                  routeService.add(definition);
                }
            } else {
                log.warn("当前网关无动态路由相关配置");
            }
            log.info("结束网关动态路由初始化...");
      } catch (Exception e) {
            log.error("初始化网关路由时发生错误", e);
      }
    }
}</pre></div>
<p>如果项目启动时,在发布路由的时候卡在 this.publisher.publishEvent(new RefreshRoutesEvent(this)); 这个地方走不下去<br />请在GatewayRouteInitConfig这个类加@RefreshScope注解</p>
<p><strong>5、测试动态路由</strong></p>
<p>前面我们已经把本地的yml中的路由注释掉了,现在我们来通过gateway服务来掉一个order服务的接口<br />接口地址:http://localhost:9010/mdx-shop-order/order/lb<br />其中9010是网关端口<br />可以看到路由成功</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010817015651.png" /></p>
<p>然后我们再在nacos配置中心加一个user服务的路由</p>
<div class="jb51code"><pre class="brush:plain;">[
    {
      "predicates":[
            {
                "args":{
                  "pattern":"/mdx-shop-order/**"
                },
                "name":"Path"
            }
      ],
      "id":"mdx-shop-order",
      "filters":[
            {
                "args":{
                  "parts":1
                },
                "name":"StripPrefix"
            }
      ],
      "uri":"lb://mdx-shop-order",
      "order":1
    },
    {
      "predicates":[
            {
                "args":{
                  "pattern":"/mdx-shop-user/**"
                },
                "name":"Path"
            }
      ],
      "id":"mdx-shop-user",
      "filters":[
            {
                "args":{
                  "parts":1
                },
                "name":"StripPrefix"
            }
      ],
      "uri":"lb://mdx-shop-user",
      "order":2
    }
]</pre></div>
<p>然后点发布<br />可以看到gateway的监听器已经监听到配置的改动</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010817015661.png" /></p>
<p>不重新启动gateway的情况下再来通过网关访问下user服务<br />接口地址:http://localhost:9010/mdx-shop-user/user/getOrderNo?userId=mdx123456<br />其中9010是网关端口<br />可以看到成功路由</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010817015661.png" /></p>
<p>到这里gateway的使用和nacos动态路由就结束了~</p>
<p>到此这篇关于SpringCloud Gateway的使用 + Nacos动态路由实践指南的文章就介绍到这了,更多相关springcloud gateway使用内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>SpringCloudGateway Nacos GitlabRunner全自动灰度服务搭建发布</li><li>Nacos+Spring Cloud Gateway动态路由配置实现步骤</li><li>Spring Cloud Gateway + Nacos 实现动态路由</li><li>基于Nacos实现Spring Cloud Gateway实现动态路由的方法</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: SpringCloud Gateway的使用 + Nacos动态路由实践指南