gateway+nacos动态路由配置

这篇具有很好参考价值的文章主要介绍了gateway+nacos动态路由配置。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

gateway+nacos动态路由配置

spring cloud微服务场景下,需要使用到路由转发组。本文将从3个方面介绍路由配置:

  1. 简单的场景
  2. 通过nacos动态路由配置
  3. 常用配置属性

1. 准备工作和前置条件

我使用的版本:

spring-boot版本: 2.3.12.RELEASE
spring-cloud版本: Hoxton.SR12
nacos版本: 2.2.9.RELEASE

各组件版本尽量与这个一致,版本参考: https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E

配置gateway路由前,需要先部署nacos、创建gateway项目、分别部署2个springboot服务(app1、app2)。这里略过,如果有人读我的文章、需要参考代码请留言,我抽空整理上传。

2. gateway简单的静态路由配置

在application.yml可以直接配置路由,下面是我的配置文件

server:
  port: 8000
spring:
  application:
    name: app-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.128.3:8848
        namespace: *****
# 简单场景使用本地配置
#      config:
#        server-addr: 192.168.128.3:8848
#        namespace: *****
    inetutils:
      preferred-networks: 192.168  # 首选IP
    gateway:
      httpclient:
        connect-timeout: 1000
      default-filters:
        - PreserveHostHeader #发送原主机头
      discovery:
        locator:
          enabled: true  # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
          lower-case-service-id: true #把服务名转换为小写
      routes:
        - id: app1
          uri: lb://app1    #lb代表负载均衡
          predicates:
            - Path=/app1/**
        - id: app2
          uri: lb://app2    #匹配后提供服务的路由地址,lb代表负载均衡
          predicates:
            - Path=/app2/**   #断言,路径相匹配的进行路由转发

3. 启动各个服务:nacos、app1、app2、gateway

先启动并登录nacos,进入服务列表页面,复制命名空间id
nacos 路由配置,spring,gateway,java,spring cloud

然后修改另外3个服务的配置文件的spring.cloud.nacos.discovery.server-addr、namespace属性,让各个服务能找到nacos。
gateway配置文件

spring:
  application:
    name: app-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.128.3:8848
        namespace: *****
    inetutils:
      preferred-networks: 192.168  # 首选IP

app1

server:
  servlet:
    context-path: /app1
spring:
  application:
    name: app1
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.128.3:8848
        namespace: *****
    inetutils:
      preferred-networks: 192.168  # 首选IP

app2

server:
  servlet:
    context-path: /app2
spring:
  application:
    name: app2
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.128.3:8848
        namespace: *****
    inetutils:
      preferred-networks: 192.168  # 首选IP

启动这3个服务。然后在nacos服务列表页面可以看到这3个服务。

浏览器访问gateway并加上app1或app2的路径,gateway会自动将/app1、/app2转发到对应的服务。

3. 动态路由配置

通过静态文件配置路由,当配置改变时要重启gateway才能更新配置,或者要开发更新配置的代码来更新。gateway提供了动态路由配置的方式来解决这个问题。

3.1 在nacos新建配置,最好和前面的命名空间相同

nacos 路由配置,spring,gateway,java,spring cloud

DataId: app-gateway-router, 配置格式:TEXT

[
    {
        "id": "app1-route",
        "uri": "lb://app1",
        "predicates": [
            {
                "name": "Path",
                "args": {
                    "pattern": "/app1/**"
                }
            }
        ]
    },
    {
        "id": "app2-route",
        "uri": "lb://app2",
        "predicates": [
            {
                "name": "Path",
                "args": {
                    "pattern": "/app2/**"
                }
            }
        ]
    }
]

3.2 在gateway增加读取动态配置的代码

DynamicGatewayRouteConfig


@Component
public class DynamicGatewayRouteConfig implements ApplicationEventPublisherAware {
    private String dataId = "app-gateway-router";
    private String group = "DEFAULT_GROUP";
    @Value("${spring.cloud.nacos.config.server-addr}")
    private String serverAddr;
    @Value("${spring.cloud.nacos.config.namespace}")
    private String namespace;
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;

    private ApplicationEventPublisher applicationEventPublisher;

    private static final List<String> ROUTE_LIST = new ArrayList<String>();

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    @NacosInjected
    private ConfigService configService;

    /**
     * 初始化网关路由 nacos config
     */
    private ConfigService initConfigService(){
        try{
            Properties properties = new Properties();
            properties.setProperty("serverAddr", serverAddr);
            if(!StringUtils.isEmpty(namespace))
                properties.setProperty("namespace", namespace);
            return configService = NacosFactory.createConfigService(properties);
        } catch (Exception e) {
            logger.error("初始化网关路由时发生错误",e);
            return null;
        }
    }

    @PostConstruct
    public void dynamicRouteByNacosListener() {
        try {
            if(StringUtils.isEmpty(group))
                group = "";
            configService = initConfigService();
            if(configService == null){
                logger.warn("initConfigService 失败!");
                return;
            }
            String configInfo = configService.getConfig(dataId, group, 3000);
            logger.info("获取网关当前配置:\r\n{}",configInfo);
            List<RouteDefinition> definitionList = JSON.parseArray(configInfo, RouteDefinition.class);
            for(RouteDefinition definition : definitionList){
                logger.info("addRoute when startup : {}",definition.toString());
                addRoute(definition);
            }
        } catch (NacosException e) {
            logger.error("发生错误!", e);
        }
        dynamicRouteByNacosListener(dataId,group);
    }


    /**
     * 监听Nacos下发的动态路由配置
     */
    public void dynamicRouteByNacosListener (String dataId, String group){
        try {
            configService.addListener(dataId, group, new Listener()  {
                @Override
                public void receiveConfigInfo(String configInfo) {
                    logger.info("进行网关更新:\n\r{}",configInfo);
                    List<RouteDefinition> definitionList = JSON.parseArray(configInfo, RouteDefinition.class);
                    for(RouteDefinition definition : definitionList){
                        logger.info("update route : {}",definition.toString());
                        updateRoute(definition);
                    }
                }
                @Override
                public Executor getExecutor() {
                    logger.info("getExecutor");
                    return null;
                }
            });
        } catch (NacosException e) {
            logger.error("从nacos接收动态路由配置出错!!!",e);
        }
    }


    public String deleteRoute(String id) {
        try {
            logger.info("gateway delete route id {}",id);
            this.routeDefinitionWriter.delete(Mono.just(id));
            return "delete success";
        } catch (Exception e) {
            return "delete fail";
        }
    }

    private String updateRoute(RouteDefinition definition) {
        try {
            logger.info("gateway update route {}",definition);
            this.routeDefinitionWriter.delete(Mono.just(definition.getId()));
        } catch (Exception e) {
            return "update fail,not find route  routeId: "+definition.getId();
        }
        try {
            routeDefinitionWriter.save(Mono.just(definition)).subscribe();
            this.applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this));
            return "success";
        } catch (Exception e) {
            return "update route fail";
        }
    }

    private void clearRoute() {
        for (String id : ROUTE_LIST) {
            this.routeDefinitionWriter.delete(Mono.just(id)).subscribe();
        }
        ROUTE_LIST.clear();
    }

    private void addRoute(RouteDefinition definition) {
        logger.info("gateway add route {}",definition);
        try {
            routeDefinitionWriter.save(Mono.just(definition)).subscribe();
            this.applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this));
        } catch (Exception e) {
            logger.error("发生错误!", e);
        }
    }
}

3.3 修改gateway配置文件

增加nacos配置中心:

      config:
        server-addr: 192.168.128.3:8848
        namespace: *****

将配置文件里静态路由的配置删除或注释

3.4. 重启gateway

重启gateway,它会连接nacos并读取配置、注册路由。至此动态路由配置完成,

4. gateway里的常用配置

常用配置请看我的下一篇: 《Spring cloud Gateway常用配置》文章来源地址https://www.toymoban.com/news/detail-702856.html

到了这里,关于gateway+nacos动态路由配置的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring Cloud Gateway 路由配置策略

    Spring Cloud Gateway 是一个基于 Spring Boot 2.x 和 Spring WebFlux 的轻量级网关服务,用于构建微服务架构中的 API 网关。它提供了一种简单、高效、灵活和可扩展的方式来路由请求到后端的微服务。 Spring Cloud Gateway 的核心特性包括: 路由功能:可以根据请求的属性(路径、参数等)将

    2024年01月20日
    浏览(41)
  • SpringCloud-Gateway路由动态配置Nacos实现

    编写配置类 properties添加配置 自定义RouteDefinitionLocator 编写GatewayDynamicConfiguration配置类

    2024年02月07日
    浏览(50)
  • Spring Cloud Day2 Nacos配置管理、Feign远程调用与Gateway服务网关

    Nacos除了可以做注册中心,同样可以做配置管理来使用。 当微服务部署的实例越来越多,达到数十、数百时,逐个修改微服务配置就会让人抓狂,而且很容易出错。我们需要一种统一配置管理方案,可以集中管理所有实例的配置。 Nacos一方面可以将配置集中管理,另一方可以

    2024年02月10日
    浏览(66)
  • Spring-cloud-gateway 路由配置方式及匹配规则

    1.1 基础路由配置⽅式 如果请求的⽬标地址,是单个的URI资源路径,配置⽂件实例如下: 各字段含义如下。 id:我们⾃定义的路由 ID,保持唯⼀ uri:⽬标服务地址 predicates:路由条件,Predicate 接受⼀个输⼊参数,返回⼀个布尔值结果。该接⼝包含多种默 认⽅法来将 Predicate

    2024年02月04日
    浏览(44)
  • (Java企业 / 公司项目)配置Gateway + Nacos应用名路由转发?

    首先看项目的gateway, 没有进行路由转发的时候的缺点 在gateway模块中的配置的路径都是写死的,到时候我们更改了IP地址又要改这个代码,会很麻烦所以我们应该怎么样做才能使得请求更加方便?这是子模块 在我们请求模块member中配置文件中加入注册中心指定模块的名称,这

    2024年02月02日
    浏览(53)
  • Spring Cloud Gateway + Nacos 灰度发布

    本文将会使用 SpringCloud Gateway 网关组件配合 Nacos 实现 灰度发布(金丝雀发布) 创建子模块 服务提供者  provider ,网关模块  gateway 父项目 pom.xml 配置 服务提供者 provider 这里我们计划引入  nacos , 所以先创建一个 nacos 配置文件  dataId  为  provider.properties , 这里用默认的命名

    2024年02月03日
    浏览(36)
  • Spring Cloud Gateway集成Nacos实现负载均衡

    💡Nacas可以用于实现Spring Cloud Gateway中网关动态路由功能,也可以基于Nacos来实现对后端服务的负载均衡,前者利用Nacos配置中心功能,后者利用Nacos服务注册功能。 接下来我们来看下Gateway集成Nacos实现负载均衡的架构图 一. 环境准备 1. 版本环境 Jdk: java.version1.8/java.version Spr

    2024年02月10日
    浏览(59)
  • Spring Cloud Gateway + Nacos 实现服务上下线无缝切换

    大家好,我是不才陈某~ 最近知识星球的球友在学习星球中的《精尽Spring Cloud Alibaba》专栏提到一个问题,相信也有很多人在线上环境遇到过,或许也因此被批过:一个集群中有某个服务突然下线,但是网关还是会去请求这个实例,所以线上就报错了,报错信息如下图: 究其

    2024年02月15日
    浏览(44)
  • Gateway基于Nacos动态路由实现

    客户端请求,首先会被 Gateway Handler Mapping 处理,用以在  路由表  中查找一个与请求匹配的  路由 , 然后将请求交由  Web Handler  处理, Web Handler  维护了一个过滤器链,链式执行这些过滤器,这些过滤器在逻辑上存在两个执行阶段  pre   与  post   Nacos 致力于帮助您发现

    2024年02月06日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包