配置文件代码:
dynamic-route:
nacos:
server-addr: http://localhost:8848
data-id: routes.json
group: DEFAULT_GROUP
namespace: b5ccc73d-b020-46b9-8f5f-cc88062d4fc0
username: nacos
password: itdunacos
属性类
package org.itdu.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@ConfigurationProperties(prefix="dynamic-route.nacos", ignoreUnknownFields = true)
@Configuration
@Data
public class NacosGatewayProperties {
private String serverAddr;
private String dataId;
private String group;
private Long timeout;
private String username;
private String password;
private String namespace;
}
实现逻辑:
密码的传入需要使用Properties作为参数:
Properties properties =new Properties();
properties.put(PropertyKeyConst.USERNAME,nacosGatewayProperties.getUsername());
properties.put(PropertyKeyConst.PASSWORD,nacosGatewayProperties.getPassword());
properties.put(PropertyKeyConst.NAMESPACE,nacosGatewayProperties.getNamespace());
properties.put(PropertyKeyConst.SERVER_ADDR,nacosGatewayProperties.getServerAddr());
然后调用工厂方法:
ConfigService configService = NacosFactory.createConfigService(properties);
来实现账户和密码的传入,如果直接使用参数传入的话,无法传入账号和密码。
package org.itdu.config;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.Component;
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;
@Component
@Slf4j
public class NacosDynamicRouteService implements ApplicationEventPublisherAware {
@Autowired
private NacosGatewayProperties nacosGatewayProperties;
@Autowired
private RouteDefinitionWriter routeDefinitionWriter;
private ApplicationEventPublisher applicationEventPublisher;
private static final List<String> ROUTE_LIST = new ArrayList<>();
@PostConstruct
public void dynamicRouteByNacosListener() {
Properties properties =new Properties();
properties.put(PropertyKeyConst.USERNAME,nacosGatewayProperties.getUsername());
properties.put(PropertyKeyConst.PASSWORD,nacosGatewayProperties.getPassword());
properties.put(PropertyKeyConst.NAMESPACE,nacosGatewayProperties.getNamespace());
properties.put(PropertyKeyConst.SERVER_ADDR,nacosGatewayProperties.getServerAddr());
try {
ConfigService configService = NacosFactory.createConfigService(properties);
String initConfigInfo =configService.getConfig(nacosGatewayProperties.getDataId(),nacosGatewayProperties.getGroup(), 5000);
// 程序首次启动, 并加载初始化路由配置
addAndPublishBatchRoute(initConfigInfo);
configService.addListener(nacosGatewayProperties.getDataId(),nacosGatewayProperties.getGroup(), new Listener() {
@Override
public void receiveConfigInfo(String configInfo) {
clearRoute();
try {
List<RouteDefinition> gatewayRouteDefinitions = JSONObject.parseArray(configInfo, RouteDefinition.class);
for (RouteDefinition routeDefinition : gatewayRouteDefinitions) {
addRoute(routeDefinition);
}
publish();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public Executor getExecutor() {
return null;
}
});
} catch (NacosException e) {
e.printStackTrace();
}
}
private void clearRoute() {
for(String id : ROUTE_LIST) {
this.routeDefinitionWriter.delete(Mono.just(id)).subscribe();
}
ROUTE_LIST.clear();
}
private void addRoute(RouteDefinition definition) {
try {
routeDefinitionWriter.save(Mono.just(definition)).subscribe();
ROUTE_LIST.add(definition.getId());
} catch (Exception e) {
e.printStackTrace();
}
}
private void publish() {
this.applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this.routeDefinitionWriter));
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
/**
* 批量 添加及发布 路由
* @param configInfo 配置文件字符串, 必须为json array格式
*/
private void addAndPublishBatchRoute(String configInfo) {
try {
clearRoute();
List<RouteDefinition> gatewayRouteDefinitions = JSONObject.parseArray(configInfo, RouteDefinition.class);
for (RouteDefinition routeDefinition : gatewayRouteDefinitions) {
addRoute(routeDefinition);
}
publish();
log.info("Dynamic config gateway route finished. {}", JSON.toJSONString(gatewayRouteDefinitions));
} catch (Exception e) {
e.printStackTrace();
}
}
}
Nacos配置文件:
[
{
"filters": [
{
"name": "StripPrefix",
"args": {
"_genkey_0": "1"
}
}
],
"id": "itdu-auth",
"order": 0,
"predicates": [{
"args": {
"pattern": "/auth/*"
},
"name": "Path"
}],
"uri":"lb://itdu-auth"
}
]
路由信息:
部分代码来源【Spring Cloud Alibaba实战(七) - Gateway搭配Nacos实现动态路由】https://blog.csdn.net/autfish/article/details/90752293
踩坑参考:【Gateway调用其他服务404】https://blog.csdn.net/embbls/article/details/94586052