透過Spring Gateway 整合Nacos實現配置管理,並且實現動態路由管理。
一、建立test-gateway專案,POM檔案如下:
二、建立專案配置檔案bootstrap.yml
server: port: 80spring: profiles: active: dev application: name: test-gateway cloud: nacos: config: namespace: ${spring。profiles。active} server-addr: http://127。0。0。1:8848 extension-configs[0]: data-id: test_gateway_commons。yml group: DEFAULT_GROUP refresh: true#Nacos動態路由配置,json格式nacos: gateway: route: config: data-id: gateway_dynamic_router group: DEFAULT_GROUP
a、test_gateway_commons。yml內容如下:
#sentinel 相關配置spring: cloud: sentinel: transport: dashboard: http://127。0。0。1:8080 port: 8719 scg: fallback: mode: response response-status: 455 response-body: error! nacos: discovery: namespace: dev server-addr: 127。0。0。1:8848management: endpoints: web: exposure: include: ‘*’
三、建立閘道器配置類 GatewayConfig.java
import org。springframework。beans。factory。annotation。Value;import org。springframework。context。annotation。Configuration;@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; }}
四、建立動態路由服務DynamicRouteServiceImpl.java
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。Service;import lombok。extern。slf4j。Slf4j;import reactor。core。publisher。Mono;/** * 動態更新路由閘道器service * 1)實現一個Spring提供的事宜推送介面ApplicationEventPublisherAware * 2)提供動態路由的基礎方式,可透過獲取bean操作該類的方式。該類提供新增路由、更新路由、刪除路由,然後實現公佈的功效。 */@Slf4j@Servicepublic class DynamicRouteServiceImpl implements ApplicationEventPublisherAware { @Autowired private RouteDefinitionWriter routeDefinitionWriter; /** * 公佈事宜 */ @Autowired private ApplicationEventPublisher publisher; @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this。publisher = applicationEventPublisher; } /** * 刪除路由 * @param id * @return */ public String delete(String id) { try { log。info(“gateway delete route id {}”,id); this。routeDefinitionWriter。delete(Mono。just(id)); return “delete success”; } catch (Exception e) { return “delete fail”; } } /** * 更新路由 * @param definition * @return */ public String update(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”; } } /** * 增添路由 * @param definition * @return */ 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”; }}
五、建立透過Nacos讀取動態路由配置服務DynamicRouteServiceImplByNacos.java
import java。util。List;import java。util。Properties;import java。util。concurrent。Executor;import javax。annotation。PostConstruct;import org。springframework。beans。factory。annotation。Autowired;import org。springframework。cloud。gateway。route。RouteDefinition;import org。springframework。context。annotation。DependsOn;import org。springframework。stereotype。Component;import com。alibaba。fastjson。JSON;import com。alibaba。nacos。api。NacosFactory;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;/** * * 透過nacos下發動態路由設定,監聽Nacos中gateway-route設定 * */@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
六、配置動態路由配置檔案gateway_dynamic_router,內容如下:
[{ “id”: “user-admin-router”, “order”: 5, “predicates”: [{ “args”: { “pattern”: “/useradmin/**” }, “name”: “Path” }], “filters”:[ { “name”:“StripPrefix”, “args”:{“_genkey_0”:1} } ], “uri”: “lb://test-user-admin”},{ “id”: “user-app-router”, “order”: 4, “predicates”: [{ “args”: { “pattern”: “/users/**” }, “name”: “Path” }], “filters”:[ { “name”:“StripPrefix”, “args”:{“_genkey_0”:1} } ], “uri”: “lb://test-user-app”}]
透過以上步驟就完成Spring Gateway 整合Nacos 實現動態路由配置功能。以後只要透過修改Nacos的配置檔案就可以時間服務的動態上下線了。不需要再重啟網關了。