小编给大家分享一下Nacos+spring cloud Gateway动态路由如何配置实现,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!前言 Nacos最近项目一直在使用,其简单灵活,支持更细粒度的命令空间,分组等为麻烦
小编给大家分享一下Nacos+spring cloud Gateway动态路由如何配置实现,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!
Nacos最近项目一直在使用,其简单灵活,支持更细粒度的命令空间,分组等为麻烦复杂的环境切换提供了方便;同时也很好支持动态路由的配置,只需要简单的几步即可。在国产的注册中心、配置中心中比较突出,容易上手,本文通过gateway、nacos-consumer、nacos-provider三个简单模块来展示:Nacos下动态路由配置。
博文中源码已上传至GitHub(https://github.com/Jian0110/learning-cloudalibaba),欢迎小伙伴们star
具体的Nacos怎么配置就不介绍了,可以参考阿里巴巴的官方介绍,这里通过windows直接本地启动开启单机模式,登录Nacos Console,创建dev的namespace,在dev下的默认分组下创建gateway-router的dataid
gateway-router的主要初始化配置如下:关于gateway的组成(id,order、predicates断言,uri)这里就不详细说明的了,可以自行百度下
[{ "id": "consumer-router", "order": 0, "predicates": [{ "args": { "pattern": "/consume@Configurationpublic class GatewayConfig { public static final long DEFAULT_TIMEOUT = 30000; public static String NACOS_SERVER_ADDR; public static String NACOS_NAMESPACE; public static String NACOS_ROUTE_DATA_ID; public static String NACOS_ROUTE_GROUP; @Value("${spring.cloud.nacos.discovery.server-addr}") public void setNacosServerAddr(String nacosServerAddr){ NACOS_SERVER_ADDR = nacosServerAddr; } @Value("${spring.cloud.nacos.discovery.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; }}
properties配置关于Nacos下读取gateway-router的配置:
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848spring.cloud.nacos.discovery.namespace=08ecd1e5-c042-410a-84d5-b0a8fbeed8eanacos.gateway.route.config.data-id=gateway-routernacos.gateway.route.config.group=DEFAULT_GROUP
第二,初始化路由,监听动态路由配置的数据源变化(2020.12.28解决删除路由不生效问题);
@Component@Slf4j@DependsOn({"gatewayConfig"}) // 依赖于gatewayConfig beanpublic class DynamicRouteServiceImplByNacos { @Autowired private DynamicRouteServiceImpl dynamicRouteService; private ConfigService configService; @PostConstruct public void init() { log.info("gateway route init..."); try{ configService = initConfigService(); if(configService == null){ log.warn("initConfigService fail"); return; } String configInfo = configService.getConfig(GatewayConfig.NACOS_ROUTE_DATA_ID, GatewayConfig.NACOS_ROUTE_GROUP, GatewayConfig.DEFAULT_TIMEOUT); log.info("获取网关当前配置:\r\n{}",configInfo); List<RouteDefinition> definitionList = JSON.parseArray(configInfo, RouteDefinition.class); for(RouteDefinition definition : definitionList){ log.info("update route : {}",definition.toString()); dynamicRouteService.add(definition); } } catch (Exception e) { log.error("初始化网关路由时发生错误",e); } dynamicRouteByNacosListener(GatewayConfig.NACOS_ROUTE_DATA_ID,GatewayConfig.NACOS_ROUTE_GROUP); } public void dynamicRouteByNacosListener (String dataId, String group){ try { configService.addListener(dataId, group, new Listener() { @Override public void receiveConfigInfo(String configInfo) { log.info("进行网关更新:\n\r{}",configInfo); List<RouteDefinition> definitionList = jsON.parseArray(configInfo, RouteDefinition.class); log.info("update route : {}",definitionList.toString()); dynamicRouteService.updateList(definitionList); } @Override public Executor getExecutor() { log.info("getExecutor\n\r"); return null; } }); } catch (NacosException e) { log.error("从nacos接收动态路由配置出错!!!",e); } } private ConfigService initConfigService(){ try{ Properties properties = new Properties(); properties.setProperty("serverAddr",GatewayConfig.NACOS_SERVER_ADDR); properties.setProperty("namespace",GatewayConfig.NACOS_NAMESPACE); return configService= NacosFactory.createConfigService(properties); } catch (Exception e) { log.error("初始化网关路由时发生错误",e); return null; } }}
第三,刷新最新的动态路由变化,实现动态增删改路由(2020.12.28解决删除路由不生效问题)
@Slf4j@Servicepublic class DynamicRouteServiceImpl implements ApplicationEventPublisherAware { @Autowired private RouteDefinitionWriter routeDefinitionWriter; @Autowired private RouteDefinitionLocator routeDefinitionLocator; @Autowired private ApplicationEventPublisher publisher; @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.publisher = applicationEventPublisher; } public String delete(String id) { try { log.info("gateway delete route id {}",id); this.routeDefinitionWriter.delete(Mono.just(id)).subscribe(); this.publisher.publishEvent(new RefreshRoutesEvent(this)); return "delete success"; } catch (Exception e) { return "delete fail"; } } public String updateList(List<RouteDefinition> definitions) { log.info("gateway update route {}",definitions); // 删除缓存routerDefinition List<RouteDefinition> routeDefinitionsExits = routeDefinitionLocator.getRouteDefinitions().buffer().blockFirst(); if (!CollectionUtils.isEmpty(routeDefinitionsExits)) { routeDefinitionsExits.forEach(routeDefinition -> { log.info("delete routeDefinition:{}", routeDefinition); delete(routeDefinition.getId()); }); } definitions.forEach(definition -> { updateById(definition); }); return "success"; } public String updateById(RouteDefinition definition) { try { log.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.publisher.publishEvent(new RefreshRoutesEvent(this)); return "success"; } catch (Exception e) { return "update route fail"; } } public String add(RouteDefinition definition) { log.info("gateway add route {}",definition); routeDefinitionWriter.save(Mono.just(definition)).subscribe(); this.publisher.publishEvent(new RefreshRoutesEvent(this)); return "success"; }}
分别启动gateway、nacos-consumer、nacos-provider三个服务,观察是否已经在Nacos上正确注册
注意:需要指定注册中心的namespace为dev的空间,即spring.cloud.nacos.discovery.namespace=08ecd1e5-c042-410a-84d5-b0a8fbeed8ea
(1)查看gateway服务的初始化启动日志:会发现可以正常从Nacos获取配置gateway-router网关配置文件内容,并进行正确路由加载...
2020-05-10 14:33:44.557 INFO 1272 --- [ main] c.g.r.DynamicRouteServiceImplByNacos : gateway route init...2020-05-10 14:33:44.578 INFO 1272 --- [ main] c.g.r.DynamicRouteServiceImplByNacos : 获取网关当前配置:[{ "id": "consumer-router", "order": 0, "predicates": [{ "args": { "pattern": "/consume/**" }, "name": "Path" }], "uri": "lb://nacos-consumer"},{ "id": "provider-router", "order": 2, "predicates": [{ "args": { "pattern": "/provide/**" }, "name": "Path" }], "uri": "lb://nacos-provider"}]2020-05-10 14:33:44.691 INFO 1272 --- [ main] c.g.r.DynamicRouteServiceImplByNacos : update route : RouteDefinition{id='consumer-router', predicates=[PredicateDefinition{name='Path', args={pattern=/consume/**}}], filters=[], uri=lb://nacos-consumer, order=0, metadata={}}2020-05-10 14:33:44.691 INFO 1272 --- [ main] c.g.service.DynamicRouteServiceImpl : gateway add route RouteDefinition{id='consumer-router', predicates=[PredicateDefinition{name='Path', args={pattern=/consume/**}}], filters=[], uri=lb://nacos-consumer, order=0, metadata={}}2020-05-10 14:33:45.192 INFO 1272 --- [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [After]2020-05-10 14:33:45.192 INFO 1272 --- [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Before]2020-05-10 14:33:45.192 INFO 1272 --- [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Between]2020-05-10 14:33:45.193 INFO 1272 --- [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Cookie]2020-05-10 14:33:45.193 INFO 1272 --- [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Header]2020-05-10 14:33:45.193 INFO 1272 --- [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Host]2020-05-10 14:33:45.194 INFO 1272 --- [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Method]2020-05-10 14:33:45.194 INFO 1272 --- [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Path]2020-05-10 14:33:45.194 INFO 1272 --- [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Query]2020-05-10 14:33:45.194 INFO 1272 --- [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [ReadBodyPredicateFactory]2020-05-10 14:33:45.194 INFO 1272 --- [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [RemoteAddr]2020-05-10 14:33:45.194 INFO 1272 --- [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [Weight]2020-05-10 14:33:45.194 INFO 1272 --- [ main] o.s.c.g.r.RouteDefinitionRouteLocator : Loaded RoutePredicateFactory [CloudFoundryRouteService]2020-05-10 14:33:45.335 INFO 1272 --- [ main] c.g.r.DynamicRouteServiceImplByNacos : update route : RouteDefinition{id='provider-router', predicates=[PredicateDefinition{name='Path', args={pattern=/provide/**}}], filters=[], uri=lb://nacos-provider, order=2, metadata={}}2020-05-10 14:33:45.335 INFO 1272 --- [ main] c.g.service.DynamicRouteServiceImpl : gateway add route RouteDefinition{id='provider-router', predicates=[PredicateDefinition{name='Path', args={pattern=/provide/**}}], filters=[], uri=lb://nacos-provider, order=2, metadata={}}2020-05-10 14:33:45.336 INFO 1272 --- [ main] c.g.r.DynamicRouteServiceImplByNacos : update route : RouteDefinition{id='github-router', predicates=[PredicateDefinition{name='Path', args={pattern=/github}}], filters=[], uri=Https://github.com, order=3, metadata={}}2020-05-10 14:33:45.336 INFO 1272 --- [ main] c.g.service.DynamicRouteServiceImpl : gateway add route RouteDefinition{id='github-router', predicates=[PredicateDefinition{name='Path', args={pattern=/github}}], filters=[], uri=https://github.com, order=3, metadata={}}
但这只能说明是初始化静态路由,下面我们改变gateway-router网关配置内容,追加github-router路由
[{ "id": "consumer-router", "order": 0, "predicates": [{ "args": { "pattern": "/consume/**" }, "name": "Path" }], "uri": "lb://nacos-consumer"},{ "id": "provider-router", "order": 2, "predicates": [{ "args": { "pattern": "/provide/**" }, "name": "Path" }], "uri": "lb://nacos-provider"},{ "id": "github-router", "order": 2, "predicates": [{ "args": { "pattern": "/github/**" }, "name": "Path" }], "uri": "https://github.com"}]
之后点击发布更新路由配置
观察gateway服务日志,有没有监听,并且进行正确的路由更新:如下日志所示,最新路由配置立马被打印,并且进行正确路由更新
2020-05-10 14:42:27.576 INFO 1272 --- [d5-b0a8fbeed8ea] c.g.r.DynamicRouteServiceImplByNacos : 进行网关更新:[{ "id": "consumer-router", "order": 0, "predicates": [{ "args": { "pattern": "/consume/**" }, "name": "Path" }], "uri": "lb://nacos-consumer"},{ "id": "provider-router", "order": 2, "predicates": [{ "args": { "pattern": "/provide/**" }, "name": "Path" }], "uri": "lb://nacos-provider"},{ "id": "github-router", "order": 2, "predicates": [{ "args": { "pattern": "/github/**" }, "name": "Path" }], "uri": "https://github.com"}]2020-05-10 14:42:27.576 INFO 1272 --- [d5-b0a8fbeed8ea] c.g.r.DynamicRouteServiceImplByNacos : update route : RouteDefinition{id='consumer-router', predicates=[PredicateDefinition{name='Path', args={pattern=/consume/**}}], filters=[], uri=lb://nacos-consumer, order=0, metadata={}}2020-05-10 14:42:27.576 INFO 1272 --- [d5-b0a8fbeed8ea] c.g.service.DynamicRouteServiceImpl : gateway update route RouteDefinition{id='consumer-router', predicates=[PredicateDefinition{name='Path', args={pattern=/consume/**}}], filters=[], uri=lb://nacos-consumer, order=0, metadata={}}2020-05-10 14:42:27.578 INFO 1272 --- [d5-b0a8fbeed8ea] c.g.r.DynamicRouteServiceImplByNacos : update route : RouteDefinition{id='provider-router', predicates=[PredicateDefinition{name='Path', args={pattern=/provide/**}}], filters=[], uri=lb://nacos-provider, order=2, metadata={}}2020-05-10 14:42:27.578 INFO 1272 --- [d5-b0a8fbeed8ea] c.g.service.DynamicRouteServiceImpl : gateway update route RouteDefinition{id='provider-router', predicates=[PredicateDefinition{name='Path', args={pattern=/provide/**}}], filters=[], uri=lb://nacos-provider, order=2, metadata={}}2020-05-10 14:42:27.580 INFO 1272 --- [d5-b0a8fbeed8ea] c.g.r.DynamicRouteServiceImplByNacos : update route : RouteDefinition{id='github-router', predicates=[PredicateDefinition{name='Path', args={pattern=/github/**}}], filters=[], uri=https://github.com, order=2, metadata={}}2020-05-10 14:42:27.580 INFO 1272 --- [d5-b0a8fbeed8ea] c.g.service.DynamicRouteServiceImpl : gateway update route RouteDefinition{id='github-router', predicates=[PredicateDefinition{name='Path', args={pattern=/github/**}}], filters=[], uri=https://github.com, order=2, metadata={}}
其实,还有办法可以知道我们的gateway服务有没有监听Nacos的gateway-router配置,那就是在Nacos Console--->监听查询----->选择配置---->输入配置文件的namespace与Group:可以发现我本地IP地址127.0.0.1对配置文件gateway-router进行了监听
(2)访问gateway网关服务:http://localhost:6003/consume/sayHello/nacos
查看consumer服务日志:
2020-05-10 14:55:07.257 INFO 6552 --- [NIO-6001-exec-2] c.n.c.controller.ConsumeController : I'm calling nacos-consumer service by dynamic gateway...
发现跳转至consumer服务,并且访问了consumer服务的CosnumerController
(3)访问gateway网关服务:http://localhost:6003/provider/sayHello/nacos
查看provider服务日志:
2020-05-10 14:56:56.144 INFO 10024 --- [nio-6002-exec-1] c.n.p.controller.ProviderController : I'm calling nacos-provider service by dynamic gateway...
发现跳转至consumer服务,并且访问了provider服务的ProviderController
(4)访问访问gateway网关服务:http://localhost:6003/github,正确跳转至github页面
1)Spring Cloud Gateway作用不光只是简单的跳转重定向,还可以实现用户的验证登录,解决跨域,日志拦截,权限控制,限流,熔断,负载均衡,黑名单和白名单机制等。是微服务架构不二的选择;
2)Nacos的配置中心支持动态获取配置文件,可以将一些全局的经常变更的配置文件放在Nacos下,需要到微服务自行获取。
2020.12.28解决删除路由不生效问题,主要是利用RouteDefinitionLocator先读取变化之前的RouteDefinition,之后删除重新再更新,或者可以实现routeDefinitionWriter、RouteDefinitionLocator重写如下方法:
Mono<Void> save(Mono<RouteDefinition> route);Mono<Void> delete(Mono<String> routeId);Flux<RouteDefinition> getRouteDefinitions();
看完了这篇文章,相信你对“Nacos+Spring Cloud Gateway动态路由如何配置实现”有了一定的了解,如果想了解更多相关知识,欢迎关注编程网精选频道,感谢各位的阅读!
--结束END--
本文标题: Nacos+Spring Cloud Gateway动态路由如何配置实现
本文链接: https://www.lsjlt.com/news/300121.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-05-12
2024-05-12
2024-05-12
2024-05-12
2024-05-12
2024-05-12
2024-05-12
2024-05-12
2024-05-12
2024-05-12
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0