zuul网关 动态路由实现核心解析

本文探讨了如何解决每次上线新项目时需要重启Zuul网关的问题。通过研究,核心在于调用ZuulHandlerMapping.setDirty(true)来触发路由更新。使用Spring的DiscoveryClientRouteLocator获取并刷新路由配置信息,同时提到了利用事件进行刷新的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近发现公司每次上线新项目都需要对网关进行重启

经过研究发现 动态路由核心代码
ZuulHandlerMapping.setDirty(true) 使执行registerHandlers()方法
在执行registerHandlers()中会获取路由配置信息

 private void registerHandlers() {
   	Collection<Route> routes = this.routeLocator.getRoutes();
   	if (routes.isEmpty()) {
   		this.logger.warn("No routes found from RouteLocator");
   	}
   	else {
   		for (Route route : routes) {
   			registerHandler(route.getFullPath(), this.zuul);
   		}
   	}
}

那么在这之前 将路由信息更新即可.
在spring中 提供了DiscoveryClientRouteLocator
于是demo如下

@RestController
@RequestMapping("/timing")
public class TimingController {


   private final DiscoveryClientRouteLocator discoveryClientRouteLocator;
   private final ZuulHandlerMapping zuulHandlerMapping;

   public TimingController(DiscoveryClientRouteLocator discoveryClientRouteLocator,
                           ZuulHandlerMapping zuulHandlerMapping) {
       this.discoveryClientRouteLocator = discoveryClientRouteLocator;
       this.zuulHandlerMapping = zuulHandlerMapping;
   }

   @PostMapping("/power/curve/timing")
   public void powerCurveTiming(@RequestBody ZuulProperties.ZuulRoute route) {
       discoveryClientRouteLocator.addRoute(route);
       zuulHandlerMapping.setDirty(true);
       System.out.println(discoveryClientRouteLocator.getClass());
   }
}

发现也可以用事件来进行刷新

private static class ZuulRefreshListener
			implements ApplicationListener<ApplicationEvent> {

		@Autowired
		private ZuulHandlerMapping zuulHandlerMapping;

		private HeartbeatMonitor heartbeatMonitor = new HeartbeatMonitor();

		@Override
		public void onApplicationEvent(ApplicationEvent event) {
			if (event instanceof ContextRefreshedEvent
					|| event instanceof RefreshScopeRefreshedEvent
					|| event instanceof RoutesRefreshedEvent
					|| event instanceof InstanceRegisteredEvent) {
				reset();
			}
			else if (event instanceof ParentHeartbeatEvent) {
				ParentHeartbeatEvent e = (ParentHeartbeatEvent) event;
				resetIfNeeded(e.getValue());
			}
			else if (event instanceof HeartbeatEvent) {
				HeartbeatEvent e = (HeartbeatEvent) event;
				resetIfNeeded(e.getValue());
			}
		}

		private void resetIfNeeded(Object value) {
			if (this.heartbeatMonitor.update(value)) {
				reset();
			}
		}

		private void reset() {
			this.zuulHandlerMapping.setDirty(true);
		}
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值