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

网友投稿 530 2022-12-05


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

简介

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

集成

Spring Cloud GateWay集成

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

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

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

org.springframework.cloud

spring-cloud-starter-gateway

org.springframework.boot

spring-boot-starter-webflux

org.springframework.boot

spring-boot-starter-actuator

Nacos集成

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

com.alibaba.nacos

nacos-client

0.9.0

动态路由

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 predicates = new ArrayList<>();

@Valid

private List 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 getPredicates() {

return predicates;

}

public void setPredicates(List predicates) {

this.predicates = predicates;

}

public List getFilters() {

return filters;

}

public void setFilters(List 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 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

[

{

"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"

}

]

查看路由信息


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:MyBatis基于pagehelper实现分页原理及代码实例
下一篇:详解Java高级特性之反射
相关文章

 发表评论

暂时没有评论,来抢沙发吧~