gateway+nocas动态路由
创建一个新项目添加maven依赖
<dependencies> <!-- nacos 服务注册发现(客户端)依赖 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!-- gateway 网关依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> </dependencies>
bootstrap.properties
#服务名称
spring.application.name=gateway-service
#nocas账号密、码、地址 spring.cloud.nacos.config.username=nacos spring.cloud.nacos.config.password=xxxxxxx spring.cloud.nacos.config.contextPath=/nacos spring.cloud.nacos.config.server-addr=xxxxxxx:8848 spring.cloud.nacos.config.file-extension=yaml
#指定读取的配置 spring.cloud.nacos.config.extension-configs[0].data-id=gateway-route.yaml spring.cloud.nacos.config.extension-configs[0].group=DEFAULT_GROUP spring.cloud.nacos.config.extension-configs[0].refresh=true
#默认public 其它空间填写namespace的Id spring.cloud.nacos.config.namespace=5436e42c-95f8-4bab-9964-125268521248
新建DynamicRouteConfig 用于加载路由
@RefreshScope @Component public class DynamicRouteConfig implements ApplicationEventPublisherAware { private static Logger log= LoggerFactory.getLogger(DynamicRouteConfig.class); @Value("${spring.cloud.nacos.config.data-id}") private String dataId; @Value("${spring.cloud.nacos.config.group}") private String group; @Value("${spring.cloud.nacos.config.server-addr}") private String serverAddr; @Value("${spring.cloud.nacos.config.namespace}") private String namespace; @Value("${spring.cloud.nacos.config.timeout}") private long timeout; @Autowired private RouteDefinitionWriter routeDefinitionWriter; @Autowired private ApplicationEventPublisher applicationEventPublisher; private static final List<String> ROUTE_LIST =new ArrayList<String>(); @PostConstruct public void dynamicRouteByNacosListener(){ try { Properties prop = new Properties(); prop.put("serverAddr", serverAddr); prop.put("namespace", namespace); ConfigService config = NacosFactory.createConfigService(prop); String content = config.getConfig(dataId, group, timeout); publisher(content); config.addListener(dataId, group, new Listener() { public void receiveConfigInfo(String config) { publisher(config); } public Executor getExecutor() { return null; } }); }catch (Exception e){ log.error("gateway动态路由加载失败,",e); } } /** * 增加路由 * * @param def * @return */ public Boolean addRoute(RouteDefinition def) { try { routeDefinitionWriter.save(Mono.just(def)).subscribe(); ROUTE_LIST.add(def.getId()); } catch (Exception e) { e.printStackTrace(); } return true; } /** * 删除路由 * * @return */ public Boolean clearRoute() { for (String id : ROUTE_LIST) { routeDefinitionWriter.delete(Mono.just(id)).subscribe(); } ROUTE_LIST.clear(); return Boolean.FALSE; } /** * 发布路由 */ private void publisher(String config) { clearRoute(); try { log.info("Start updating dynamic routing ...."); List<RouteDefinition> routeDefinitionList = JSONObject.parseArray(config, RouteDefinition.class); for (RouteDefinition route : routeDefinitionList) { log.info(route.toString()); addRoute(route); } applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this.routeDefinitionWriter)); log.info("update completed "); } catch (Exception e) { log.error("Failed to update routing information", e); e.printStackTrace(); } } public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { applicationEventPublisher = applicationEventPublisher; } }
nocas配置中添加 gateway-route.yaml 配置,修改路由配置实时生效
[ { "filters": [ { "args": { "parts": "1" }, "name": "StripPrefix" } ], "id": "order_route", "order": -1, "predicates": [ { "args": { "pattern": "/service-order/**" }, "name": "Path" } ], "uri": "lb://service-openfeign" }, { "filters": [ { "args": { "parts": "1" }, "name": "StripPrefix" } ], "id": "stock_route", "order": 0, "predicates": [ { "args": { "pattern": "/service-stock/**" }, "name": "Path" } ], "uri": "lb://service-openfeign" } ]