程序配置
引入依赖
<!--gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--负载均衡-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!--bootstrap支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!--nacos服务注册-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--nacos配置管理-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
bootstrap.yaml配置与普通服务配置一致
结合nacos配置动态路由
nacos额外配置服务路由信息(json)
[
{
"id": "system",
"uri": "lb://system-server",
"filters": [],
"predicates": [
{
"name": "Path",
"args": {"_genkey_0": "/system/**"}
}
]
},
{
"id": "ai",
"uri": "lb://ai-server",
"filters": [],
"predicates": [
{
"name": "Path",
"args": {"_genkey_0": "/ai/**"}
}
]
}
]
创建动态路由配置类
package online.initline.boot.gateway.config;
import cn.hutool.json.JSONUtil;
import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
* @author zck
*/
@Component
@Slf4j
@RequiredArgsConstructor
public class DynamicRouteConfig {
// nacos配置管理
private final NacosConfigManager nacosConfigManager;
// 路由写入
private final RouteDefinitionWriter routeDefinitionWriter;
// 存储当前路由
private final Set<String> routeIds = new HashSet<>();
// nacos配置路由文件对应id
private final String dataId = "gateway-routes.json";
// 配置分组
private final String groupId = "DEFAULT_GROUP";
// 创建线程池
private static final Executor EXECUTOR = Executors.newSingleThreadExecutor();
@PostConstruct
public void initRouteConfigListener() {
try {
// 项目启动时 先拉取一次配置 并配置监听器
String configInfo = nacosConfigManager.getConfigService()
.getConfigAndSignListener(dataId, groupId, 5000, new Listener() {
@Override
public Executor getExecutor() {
return EXECUTOR;
}
@Override
public void receiveConfigInfo(String config) {
updateRouteConfig(config);
}
});
// 第一次拉取到配置时,也需要更新路由表
updateRouteConfig(configInfo);
} catch (NacosException e) {
log.error("Failed to initialize route config listener", e);
}
}
private void updateRouteConfig(String configInfo) {
try {
// 解析配置文件
List<RouteDefinition> routeDefinitionList = JSONUtil.toList(configInfo, RouteDefinition.class);
// 删除旧路由表
routeIds.forEach(id -> routeDefinitionWriter.delete(Mono.just(id)).subscribe());
routeIds.clear();
// 更新路由表
routeDefinitionList.forEach(routeDefinition -> {
routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
// 记录路由id 便于下次删除
routeIds.add(routeDefinition.getId());
});
} catch (Exception e) {
log.error("Failed to update route config", e);
}
}
}
评论区