spring cloud gateway + nacos 实现 动态路由配置、秒级上下线(二)

tech2026-04-17  1

之前已经知道了nacos服务变更通知的流程,那么现在就是实现获取服务变更 并实现秒级上下线

通过源码回溯可以知道EventDispatcher对象是由NacosNamingService对象创建并管理,在往上 能知道这个对象又是由NacosDiscoveryProperties对象管理,而这个对象 就是nacos-config 的配置信息对象,那么他必然是由spring管理的,所以Resource 注入完事,

NacosDiscoveryProperties 管理的代码

public NamingService namingServiceInstance() { if (null != namingService) { return namingService; } try { namingService = NacosFactory.createNamingService(getNacosProperties()); } catch (Exception e) { log.error("create naming service error!properties={},e=,", this, e); return null; } return namingService; }

按照上一篇 所看到的流程 ,我还需要一个实现EventListener接口的对象 去加入监听并处理

@Component public class ServiceEventListener implements EventListener { @Resource private NamedContextFactory factory; /** * 监听服务的变更 并销毁原有的 服务列表 * @param event */ @Override public void onEvent(Event event) { if (event instanceof NamingEvent){ //销毁服务上下文 factory.destroy(); } } }

当收到监听且是服务变更的监听对象 则直接销毁gateway 的服务表上下文,可以精确的更改,但是据我看到的方法应该只能反射修改内部的map

最后获取服务列表并添加监听器

@Resource private NacosDiscoveryProperties discoveryProperties; @Resource private NacosServiceDiscovery serviceDiscovery; @Resource private ServiceEventListener eventListener; private volatile NamingService naming; protected static volatile List<String> services = new ArrayList<>(); protected volatile long time = 30000; @Autowired public void init(){ try { naming = discoveryProperties.namingServiceInstance(); services = serviceDiscovery.getServices(); services.forEach(this::addServiceListener); //TODO 定时监听新的 服务 new Thread(()->{ for (;;){ try { Thread.sleep(time); List<String> newServices = serviceDiscovery.getServices(); for (String service : newServices){ if (!services.contains(service)){ services.add(service); addServiceListener(service); } } }catch (Exception e){ e.printStackTrace(); } } }).start(); }catch (Exception e){ e.printStackTrace(); } } /** * 新的服务添加监听 * @param serviceName */ public void addServiceListener(String serviceName){ try { naming.subscribe(serviceName, eventListener); }catch (Exception e){ e.printStackTrace(); } }

gateway的秒级的上下线就实现了

最新回复(0)