基于Nacos实现Spring Cloud Gateway实现动态路由的方法

作者:java圈 时间:2022-04-14 07:18:56 

简介

该文档主要介绍以Nacos为配置中心,实现Spring Cloud GateWay 实现动态路由的功能。Spring Cloud Gateway启动时候,就将路由配置和规则加载到内存里,无法做到不重启网关就可以动态的对应路由的配置和规则进行增加,修改和删除。通过nacos的配置下发的功能可以实现在不重启网关的情况下,实现动态路由。

集成

Spring Cloud GateWay集成

spring-cloud-starter-gateway:路由转发、请求过滤(权限校验、限流以及监控等)

spring-boot-starter-webflux:反应式Web框架

spring-boot-starter-actuator:监控系统健康


 <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Nacos集成

nacos-client:nacos客户端,现在用比较新的版本0.9.0


 <dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>0.9.0</version>
</dependency>

动态路由

DynamicRouteServiceImpl:提供动态路由的基础方法,可通过获取bean操作该类的方法。该类提供新增路由、更新路由、删除路由,然后实现发布的功能。


@Service
public class DynamicRouteServiceImpl implements ApplicationEventPublisherAware {

@Autowired
 private RouteDefinitionWriter routeDefinitionWriter;

private ApplicationEventPublisher publisher;

/**
  * 增加路由
  * @param definition
  * @return
  */
 public String add(RouteDefinition definition) {
   routeDefinitionWriter.save(Mono.just(definition)).subscribe();
   this.publisher.publishEvent(new RefreshRoutesEvent(this));
   return "success";
 }

/**
  * 更新路由
  * @param definition
  * @return
  */
 public String update(RouteDefinition definition) {
   try {
     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.publisher.publishEvent(new RefreshRoutesEvent(this));
     return "success";
   } catch (Exception e) {
     return "update route fail";
   }

}
 /**
  * 删除路由
  * @param id
  * @return
  */
 public String delete(String id) {
   try {
     this.routeDefinitionWriter.delete(Mono.just(id));
     return "delete success";
   } catch (Exception e) {
     e.printStackTrace();
     return "delete fail";
   }

}

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

}

RouteDefinition: 提供路由实体类,主要有predicates匹配来自用户的请求,filters服务路由


@Validated
public class RouteDefinition {
@NotEmpty
private String id = UUID.randomUUID().toString();

@NotEmpty
@Valid
private List<PredicateDefinition> predicates = new ArrayList<>();

@Valid
private List<FilterDefinition> filters = new ArrayList<>();

@NotNull
private URI uri;

private int order = 0;

public RouteDefinition() {}

public RouteDefinition(String text) {
int eqIdx = text.indexOf("=");
if (eqIdx <= 0) {
throw new ValidationException("Unable to parse RouteDefinition text '" + text + "'" +
", must be of the form name=value");
}

setId(text.substring(0, eqIdx));

String[] args = tokenizeToStringArray(text.substring(eqIdx+1), ",");

setUri(URI.create(args[0]));

for (int i=1; i < args.length; i++) {
this.predicates.add(new PredicateDefinition(args[i]));
}
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public List<PredicateDefinition> getPredicates() {
return predicates;
}

public void setPredicates(List<PredicateDefinition> predicates) {
this.predicates = predicates;
}

public List<FilterDefinition> getFilters() {
return filters;
}

public void setFilters(List<FilterDefinition> filters) {
this.filters = filters;
}

public URI getUri() {
return uri;
}

public void setUri(URI uri) {
this.uri = uri;
}

public int getOrder() {
return order;
}

public void setOrder(int order) {
this.order = order;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RouteDefinition routeDefinition = (RouteDefinition) o;
return Objects.equals(id, routeDefinition.id) &&
Objects.equals(predicates, routeDefinition.predicates) &&
Objects.equals(order, routeDefinition.order) &&
Objects.equals(uri, routeDefinition.uri);
}

@Override
public int hashCode() {
return Objects.hash(id, predicates, uri);
}

@Override
public String toString() {
return "RouteDefinition{" +
"id='" + id + '\'' +
", predicates=" + predicates +
", filters=" + filters +
", uri=" + uri +
", order=" + order +
'}';
}
}

NacosGatewayProperties:自定义属性绑定值,可通过配置文件配置属性。


@ConfigurationProperties(prefix="nacos", ignoreUnknownFields = true)
@Configuration
public class NacosGatewayProperties {

private String address;

private String dataId;

private String groupId;

private Long timeout;

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

public String getDataId() {
return dataId;
}

public void setDataId(String dataId) {
this.dataId = dataId;
}

public String getGroupId() {
return groupId;
}

public void setGroupId(String groupId) {
this.groupId = groupId;
}

public Long getTimeout() {
return timeout;
}

public void setTimeout(Long timeout) {
this.timeout = timeout;
}
}

DynamicRouteServiceImplByNacos: 实现runner,通过nacos下发动态路由配置


@Component
public class DynamicRouteServiceImplByNacos implements CommandLineRunner{

@Autowired
 private DynamicRouteServiceImpl dynamicRouteService;

@Autowired
 private NacosGatewayProperties nacosGatewayProperties;

/**
  * 监听Nacos Server下发的动态路由配置
  * @param dataId
  * @param group
  */
 public void dynamicRouteByNacosListener (){
   try {
     ConfigService configService=NacosFactory.createConfigService(nacosGatewayProperties.getAddress());
     String content = configService.getConfig(nacosGatewayProperties.getDataId(), nacosGatewayProperties.getGroupId(), nacosGatewayProperties.getTimeout());
     System.out.println(content);
     configService.addListener(nacosGatewayProperties.getDataId(), nacosGatewayProperties.getGroupId(), new Listener() {
       @Override
       public void receiveConfigInfo(String configInfo) {
       List<RouteDefinition> list = JsonUtils.toList(configInfo, RouteDefinition.class);
       list.forEach(definition->{
       dynamicRouteService.update(definition);
       });
       }
       @Override
       public Executor getExecutor() {
         return null;
       }
     });
   } catch (NacosException e) {
     e.printStackTrace();
   }
 }

@Override
public void run(String... args) throws Exception {
   dynamicRouteByNacosListener();

}

}

nacos配置下发

nacos配置


nacos:
address: 127.0.0.1:8848
data-id: dhap-gateway #
group-id: AAA
timeout: 5000

nacos属性文件定义

新建dataID为
groupID为AAA

基于Nacos实现Spring Cloud Gateway实现动态路由的方法


[
{
"filters": [],
"id": "blog1",
"order": 0,
"predicates": [{
"args": {
"pattern": "/z"
},
"name": "Path"
}],
"uri": "https://blog.csdn.net/zhangchangbin123"
},
{
"filters": [],
"id": "blog1",
"order": 0,
"predicates": [{
"args": {
"pattern": "/c"
},
"name": "Path"
}],
"uri": "https://blog.csdn.net/zhangchangbin123"
}
]

查看路由信息

基于Nacos实现Spring Cloud Gateway实现动态路由的方法

基于Nacos实现Spring Cloud Gateway实现动态路由的方法

基于Nacos实现Spring Cloud Gateway实现动态路由的方法

基于Nacos实现Spring Cloud Gateway实现动态路由的方法

来源:https://blog.csdn.net/zhangchangbin123/article/details/89310353

标签:Spring,Cloud,Gateway,动态路由
0
投稿

猜你喜欢

  • 在java poi导入Excel通用工具类示例详解

    2022-11-11 21:16:00
  • Java毕业设计实战之在线网盘系统的实现

    2023-03-05 05:42:47
  • Android 实现左滑出现删除选项

    2021-05-28 12:05:59
  • Eclipse自定义启动画面和图标的方法介绍

    2022-05-14 09:27:13
  • JAVA实现扫描线算法(超详细)

    2023-06-30 13:33:20
  • Android中EditText和AutoCompleteTextView设置文字选中颜色方法

    2022-12-05 04:45:30
  • Android中通过Notification&NotificationManager实现消息通知

    2023-01-01 16:57:05
  • gradle使用maven-publish发布jar包上传到私有maven配置

    2022-11-22 07:07:54
  • 深入理解Java虚拟机体系结构

    2021-09-15 19:46:53
  • SpringBoot遇到的坑@Qualifier报红的解决

    2022-06-03 07:49:55
  • zookeeper概述图文详解

    2021-12-07 15:46:03
  • C#服务端图片打包下载实现代码解析

    2023-01-26 07:36:23
  • Eclipse IDE可支持Java 14編程

    2022-09-06 10:14:43
  • Android生成带圆角的Bitmap图片

    2022-09-08 11:18:19
  • SpringBoot JSON全局日期格式转换器实现方式

    2021-10-03 10:07:28
  • java动态口令登录实现过程详解

    2022-01-01 10:16:28
  • Java数组的基本学习教程

    2021-07-14 05:08:00
  • C# 枚举Color并展示各种颜色效果的示例

    2023-10-24 21:27:27
  • Android实现简单手电筒功能

    2023-09-17 19:50:27
  • Java精品项目瑞吉外卖之员工信息管理篇

    2023-07-29 07:43:36
  • asp之家 软件编程 m.aspxhome.com