nacos gateway动态路由实战

时间:2022-01-20 14:01:05

nacos gateway动态路由

说明:本次测试使用的gateway是2.2.2.RELEASE版本,其他版本可能存在不同

一、引入本次测试需要的pom依赖

     <!--gateway网关依赖-->
      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-gateway</artifactId>
      </dependency>
      <!--nacos依赖-->
      <dependency>
          <groupId>com.alibaba.cloud</groupId>
          <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
      </dependency>
      <dependency>
          <groupId>com.alibaba.cloud</groupId>
          <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
      </dependency>
      <!--json工具包-->
      <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>fastjson</artifactId>
          <version>1.2.47</version>
      </dependency>

二、配置文件设置(*配置文件不生效的把名字改为bootstrap.yml)

server:
port: 8200

spring:
application:
  name: lc-gateway

cloud:
  nacos:
    discovery:
      #注册中心地址
      server-addr: 106.12.146.239:8848
    config:
      server-addr: 106.12.146.239:8848
      # 配置中心-指定命名空间
      namespace: bb79a8c4-e4e1-4a27-bceb-0810f278b5aa
      # 指定配置文件后缀
      file-extension: yaml
      #配置组
      group: DEFAULT_GROUP
      #配置dateId
      data-id: lc-gateway
      #获取配置超时时间
      timeout: 5000

  gateway:
    #设置超时时间默认
    httpclient:
      connect-timeout: 1000
      response-timeout: 5s

ps:这里集成了nacos配置中心想了解详情请移步spring cloud集成nacos配置中心

三、动态路由实现

package com.lc.api.gateway.config;  
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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; 
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Executor;

/**
* 动态路由,可以通过获取Bean才做该类,提供增删改查已经发布功能
*
* @Author: lc
* @Date: 2020/7/8 15:49
*/
@Service
public class DynamicRouteConfig implements ApplicationEventPublisherAware { 
  private static final Logger logger = LoggerFactory.getLogger(DynamicRouteConfig.class); 
  @Autowired
  private RouteDefinitionWriter routedefinitionWriter; 
  private ApplicationEventPublisher publisher; 
  @Value("${spring.cloud.nacos.config.data-id}")
  private String dataId;
  @Value("${spring.cloud.nacos.config.group}")
  private String group;
  @Value("${spring.cloud.nacos.config.server-addr}")
  private String serverAddr;
  @Value("${spring.cloud.nacos.config.namespace}")
  private String namespace;
  @Value("${spring.cloud.nacos.config.timeout}")
  private long timeout; 
  private static final List<String> ROUTE_LIST = new ArrayList<>();

  @PostConstruct
  public void dynamicRouteByNacosListener() {
      try {
          Properties prop = new Properties();
          prop.put("serverAddr", serverAddr);
          prop.put("namespace", namespace);
          ConfigService config = NacosFactory.createConfigService(prop);
          String content = config.getConfig(dataId, group, timeout);
          publisher(content);
          config.addListener(dataId, group, new Listener() {
              @Override
              public void receiveConfigInfo(String config) {
                  publisher(config);
              }

              @Override
              public Executor getExecutor() {
                  return null;
              }
          });
      } catch (Exception e) {
          e.printStackTrace();
      }
  }

  /**
   * 增加路由
   *
   * @param def
   * @return
   */
  public Boolean addRoute(RouteDefinition def) {
      try {
          routedefinitionWriter.save(Mono.just(def)).subscribe();
          ROUTE_LIST.add(def.getId());
      } catch (Exception e) {
          e.printStackTrace();
      }
      return true;
  }

  /**
   * 删除路由
   *
   * @return
   */
  public Boolean clearRoute() {
      for (String id : ROUTE_LIST) {
          routedefinitionWriter.delete(Mono.just(id)).subscribe();
      }
      ROUTE_LIST.clear();
      return Boolean.FALSE;
  }

  /**
   * 发布路由
   */
  private void publisher(String config) {
      clearRoute();
      try {
          logger.info("Start updating dynamic routing ....");
          List<RouteDefinition> routeDefinitionList = JSONObject.parseArray(config, RouteDefinition.class);
          for (RouteDefinition route : routeDefinitionList) {
              logger.info(route.toString());
              addRoute(route);
          }
          publisher.publishEvent(new RefreshRoutesEvent(this.routedefinitionWriter));
          logger.info("update completed ");
      } catch (Exception e) {
          logger.error("Failed to update routing information", e);
          e.printStackTrace();
      } 
  }

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

四、nacos配置中心设置

1.说明

nacos gateway动态路由实战

2.新建一个网关配置

nacos gateway动态路由实战

3. 添加配置格式如下

nacos gateway动态路由实战

这里我就不注释了大家应该都能看懂

[
  {
      "filters": [
          {
              "args": {
                  "parts": "1"
              },
              "name": "StripPrefix"
          }
      ],
      "id": "authent1",
      "order": -1,
      "predicates": [
          {
              "args": {
                  "pattern": "/authent/**"
              },
              "name": "Path"
          }
      ],
      "uri": "lb://lc-authenticate"
  }
]

五、测试

nacos gateway动态路由实战

 

gateway网关相关配置

创建,使用initilizer,

  • Group:com.atguigu.gulimall
  • Artifact: gulimall-gateway
  • package:com.atguigu.gulimall.gateway

搜索gateway选中。

pom.xml里加上common依赖, 修改jdk版本

在启动类中添加注解@EeableDiscoveryClient

nacos gateway动态路由实战

配置nacos注册中心地址

spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
spring.application.name=gulimall-gateway
server.port=88

bootstrap.properties 填写配置中心地址

spring.application.name=gulimall-gateway
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=ab66aff2-0bd5-4f80-8a68-760d6ff7d96d

nacos里创建命名空间gateway

然后在命名空间里创建文件guilmall-gateway.yml

spring:
  application:
      name: gulimall-gateway

在主类中屏蔽数据源

nacos gateway动态路由实战

在项目里创建application.yml

spring:
cloud:
  gateway:
    routes:
      - id: after_route
        uri: https://www.xiaomi.com
        predicates:
          - Query=url,xiaomi
#            若参数等于断言 则跳转到指定的uri

运行结果

nacos gateway动态路由实战

以上为个人经验,希望能给大家一个参考,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/qq_41988504/article/details/107227870