课程名称:Spring Cloud / Alibaba 微服务架构实战
课程章节:第7章-SpringCloud Gateway微服务
课程讲师:张勤一
课程内容:
1.集成Alibaba Nacos实现动态路由配置
1.1 静态路由配置与动态路由配置
-
动态路由配置
静态路由配置写在配置文件,端点是:spring.cloud.gateway
gateway:
routers:- id: path_route
uri: ip:port/xxx/xx
predicates: - Path: /xxx/{xx}
缺点是每次改动都需要网关模块重新部署。
- id: path_route
-
动态路由配置
路由信息在Alibaba Nacos 中维护,可以实现动态变更。
package com.imooc.ecommerce.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* 读取 Nacos 相关的配置项,用于配置监听器
*/
@Configuration
public class GatewayConfig {
/** 读取配置的超时时间*/
public static final long DEFAULT_TIMEOUT = 30000;
/** Nacos 服务器地址*/
public static String NACOS_SERVER_ADDR;
/** 命名空间*/
public static String NACOS_NAMESPACE;
/** data-id */
public static String NACOS_ROUTE_DATA_ID;
/** 分组id */
public static String NACOS_ROUTE_GROUP;
@Value("${spring.cloud.nacos.discover.server-addr}")
public void setNacosServerAddr(String nacosServerAddr) {
NACOS_SERVER_ADDR = nacosServerAddr;
}
@Value("${spring.cloud.nacos.discover.namespace}")
public void setNacosNamespace(String nacosNamespace){
NACOS_NAMESPACE = nacosNamespace;
}
@Value("${nacos.gateway.route.config.data-id}")
public void setNacosRouteDataId(String nacosRouteDataId){
NACOS_ROUTE_DATA_ID = nacosRouteDataId;
}
@Value("${nacos.gateway.route.config.group}")
public void setNacosRouteGroup(String nacosRouteGroup){
NACOS_ROUTE_GROUP = nacosRouteGroup;
}
}
package com.imooc.ecommerce.config;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
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 java.util.List;
@Slf4j
@Service
public class DynamicRouteServiceImpl implements ApplicationEventPublisherAware {
/** 写路由定义 */
private final RouteDefinitionWriter routeDefinitionWriter;
/** 获取路由定义 */
private final RouteDefinitionLocator routeDefinitionLocator;
/** 事件发布 */
private ApplicationEventPublisher publisher;
public DynamicRouteServiceImpl(RouteDefinitionWriter routeDefinitionWriter, RouteDefinitionLocator routeDefinitionLocator){
this.routeDefinitionWriter = routeDefinitionWriter;
this.routeDefinitionLocator = routeDefinitionLocator;
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
//完成事件推送句柄的初始化
this.publisher = applicationEventPublisher;
}
/**
* 增加路由定义
* @param definition
* @return
*/
public String addRouteDefinition(RouteDefinition definition){
log.info("gateway add route: [{}]", definition);
//保存路由配置并发布
routeDefinitionWriter.save(Mono.just(definition)).subscribe();
//发布事件通知Gateway, 同步新增的路由定义
this.publisher.publishEvent(new RefreshRoutesEvent(this));
return "success";
}
/**
* 更新路由
*/
public String updateList(List<RouteDefinition> definitions){
log.info("gateway update route: [{}]", definitions);
//先拿到当前 Gateway中存储的路由定义
List<RouteDefinition> routeDefinitionsExits = routeDefinitionLocator.getRouteDefinitions().buffer().blockFirst();
if (!CollectionUtils.isEmpty(routeDefinitionsExits)){
//清楚掉之前所有旧的路由定义
routeDefinitionsExits.forEach(route -> {
log.info("delete route definition: [{}]", route);
deleteById(route.getId());
});
}
//把更新的路由定义同步到 gateway 中
definitions.forEach(definition -> {updateByRouteDefinition(definition);});
return "success";
}
/**
* 根据路由id删除路由配置
* @param id
* @return
*/
private String deleteById(String id) {
try {
log.info("gateway delete route id: [{}]", id);
this.routeDefinitionWriter.delete(Mono.just(id)).subscribe();
return "delete success";
} catch (Exception ex) {
log.error("gateway delete route fail: [{}]", ex.getMessage(), ex);
return "delete fail";
}
}
/**
* 更新路由
* 删除 + 新增 = 更新
*/
private String updateByRouteDefinition(RouteDefinition definition) {
try {
log.info("gateway update route: [{}]", definition);
this.routeDefinitionWriter.delete(Mono.just(definition.getId()));
} catch(Exception ex){
log.error("update fail, not find route routeId:" + definition.getId());
return "update fail";
}
try {
this.routeDefinitionWriter.save(Mono.just(definition)).subscribe();
this.publisher.publishEvent(new RefreshRoutesEvent(this));
return "success";
} catch(Exception ex) {
log.error("update fail, not find route routeId:" + definition.getId());
return "update fail";
}
}
}
课程截图:661词
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦