gateway+nacos动态路由配置
spring cloud微服务场景下,需要使用到路由转发组。本文将从3个方面介绍路由配置:
- 简单的场景
- 通过nacos动态路由配置
- 常用配置属性
1. 准备工作和前置条件
我使用的版本:
spring-boot版本: 2.3.12.RELEASE
spring-cloud版本: Hoxton.SR12
nacos版本: 2.2.9.RELEASE
各组件版本尽量与这个一致,版本参考: https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E
配置gateway路由前,需要先部署nacos、创建gateway项目、分别部署2个springboot服务(app1、app2)。这里略过,如果有人读我的文章、需要参考代码请留言,我抽空整理上传。
2. gateway简单的静态路由配置
在application.yml可以直接配置路由,下面是我的配置文件
server:
port: 8000
spring:
application:
name: app-gateway
cloud:
nacos:
discovery:
server-addr: 192.168.128.3:8848
namespace: *****
# 简单场景使用本地配置
# config:
# server-addr: 192.168.128.3:8848
# namespace: *****
inetutils:
preferred-networks: 192.168 # 首选IP
gateway:
httpclient:
connect-timeout: 1000
default-filters:
- PreserveHostHeader #发送原主机头
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
lower-case-service-id: true #把服务名转换为小写
routes:
- id: app1
uri: lb://app1 #lb代表负载均衡
predicates:
- Path=/app1/**
- id: app2
uri: lb://app2 #匹配后提供服务的路由地址,lb代表负载均衡
predicates:
- Path=/app2/** #断言,路径相匹配的进行路由转发
3. 启动各个服务:nacos、app1、app2、gateway
先启动并登录nacos,进入服务列表页面,复制命名空间id
然后修改另外3个服务的配置文件的spring.cloud.nacos.discovery.server-addr、namespace属性,让各个服务能找到nacos。
gateway配置文件
spring:
application:
name: app-gateway
cloud:
nacos:
discovery:
server-addr: 192.168.128.3:8848
namespace: *****
inetutils:
preferred-networks: 192.168 # 首选IP
app1
server:
servlet:
context-path: /app1
spring:
application:
name: app1
cloud:
nacos:
discovery:
server-addr: 192.168.128.3:8848
namespace: *****
inetutils:
preferred-networks: 192.168 # 首选IP
app2
server:
servlet:
context-path: /app2
spring:
application:
name: app2
cloud:
nacos:
discovery:
server-addr: 192.168.128.3:8848
namespace: *****
inetutils:
preferred-networks: 192.168 # 首选IP
启动这3个服务。然后在nacos服务列表页面可以看到这3个服务。
浏览器访问gateway并加上app1或app2的路径,gateway会自动将/app1、/app2转发到对应的服务。
3. 动态路由配置
通过静态文件配置路由,当配置改变时要重启gateway才能更新配置,或者要开发更新配置的代码来更新。gateway提供了动态路由配置的方式来解决这个问题。
3.1 在nacos新建配置,最好和前面的命名空间相同
DataId: app-gateway-router, 配置格式:TEXT
[
{
"id": "app1-route",
"uri": "lb://app1",
"predicates": [
{
"name": "Path",
"args": {
"pattern": "/app1/**"
}
}
]
},
{
"id": "app2-route",
"uri": "lb://app2",
"predicates": [
{
"name": "Path",
"args": {
"pattern": "/app2/**"
}
}
]
}
]
3.2 在gateway增加读取动态配置的代码
DynamicGatewayRouteConfig
@Component
public class DynamicGatewayRouteConfig implements ApplicationEventPublisherAware {
private String dataId = "app-gateway-router";
private String group = "DEFAULT_GROUP";
@Value("${spring.cloud.nacos.config.server-addr}")
private String serverAddr;
@Value("${spring.cloud.nacos.config.namespace}")
private String namespace;
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private RouteDefinitionWriter routeDefinitionWriter;
private ApplicationEventPublisher applicationEventPublisher;
private static final List<String> ROUTE_LIST = new ArrayList<String>();
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
@NacosInjected
private ConfigService configService;
/**
* 初始化网关路由 nacos config
*/
private ConfigService initConfigService(){
try{
Properties properties = new Properties();
properties.setProperty("serverAddr", serverAddr);
if(!StringUtils.isEmpty(namespace))
properties.setProperty("namespace", namespace);
return configService = NacosFactory.createConfigService(properties);
} catch (Exception e) {
logger.error("初始化网关路由时发生错误",e);
return null;
}
}
@PostConstruct
public void dynamicRouteByNacosListener() {
try {
if(StringUtils.isEmpty(group))
group = "";
configService = initConfigService();
if(configService == null){
logger.warn("initConfigService 失败!");
return;
}
String configInfo = configService.getConfig(dataId, group, 3000);
logger.info("获取网关当前配置:\r\n{}",configInfo);
List<RouteDefinition> definitionList = JSON.parseArray(configInfo, RouteDefinition.class);
for(RouteDefinition definition : definitionList){
logger.info("addRoute when startup : {}",definition.toString());
addRoute(definition);
}
} catch (NacosException e) {
logger.error("发生错误!", e);
}
dynamicRouteByNacosListener(dataId,group);
}
/**
* 监听Nacos下发的动态路由配置
*/
public void dynamicRouteByNacosListener (String dataId, String group){
try {
configService.addListener(dataId, group, new Listener() {
@Override
public void receiveConfigInfo(String configInfo) {
logger.info("进行网关更新:\n\r{}",configInfo);
List<RouteDefinition> definitionList = JSON.parseArray(configInfo, RouteDefinition.class);
for(RouteDefinition definition : definitionList){
logger.info("update route : {}",definition.toString());
updateRoute(definition);
}
}
@Override
public Executor getExecutor() {
logger.info("getExecutor");
return null;
}
});
} catch (NacosException e) {
logger.error("从nacos接收动态路由配置出错!!!",e);
}
}
public String deleteRoute(String id) {
try {
logger.info("gateway delete route id {}",id);
this.routeDefinitionWriter.delete(Mono.just(id));
return "delete success";
} catch (Exception e) {
return "delete fail";
}
}
private String updateRoute(RouteDefinition definition) {
try {
logger.info("gateway update route {}",definition);
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.applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this));
return "success";
} catch (Exception e) {
return "update route fail";
}
}
private void clearRoute() {
for (String id : ROUTE_LIST) {
this.routeDefinitionWriter.delete(Mono.just(id)).subscribe();
}
ROUTE_LIST.clear();
}
private void addRoute(RouteDefinition definition) {
logger.info("gateway add route {}",definition);
try {
routeDefinitionWriter.save(Mono.just(definition)).subscribe();
this.applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this));
} catch (Exception e) {
logger.error("发生错误!", e);
}
}
}
3.3 修改gateway配置文件
增加nacos配置中心:
config:
server-addr: 192.168.128.3:8848
namespace: *****
将配置文件里静态路由的配置删除或注释
3.4. 重启gateway
重启gateway,它会连接nacos并读取配置、注册路由。至此动态路由配置完成,文章来源:https://www.toymoban.com/news/detail-702856.html
4. gateway里的常用配置
常用配置请看我的下一篇: 《Spring cloud Gateway常用配置》文章来源地址https://www.toymoban.com/news/detail-702856.html
到了这里,关于gateway+nacos动态路由配置的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!