最近发现公司每次上线新项目都需要对网关进行重启
经过研究发现 动态路由核心代码
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);
}
}