Spring Cloud Zuul 路由自动刷新原理
现象
发布新服务,然后在数据库配置了路由,使用服务路径访问404。然后重新发布新的服务,就可以继续访问得到
(1)配置了路由第一次访问
(2)重新发布后访问
分析
(1)查找RefreshableRouteLocator.refresh
方法
@Component
public class NacosRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {
public NacosRouteLocator(ServerProperties serverProperties, ZuulProperties properties) {
super(serverProperties.getServlet().getContextPath(), properties);
}
@Override
public void refresh() {
doRefresh();
}
@Override
protected Map<String, ZuulProperties.ZuulRoute> locateRoutes() {
//默认从配置文件中加载路由信息
//return super.locateRoutes());
//定制路由, 可以使用db的配置管理进行路由
Map<String, ZuulProperties.ZuulRoute> routesMap = DbUtils.loadRoutes();
return routesMap;
}
}
(2)ZuulHandlerMapping.setDirty
方法
public class ZuulHandlerMapping extends AbstractUrlHandlerMapping {
public void setDirty(boolean dirty) {
this.dirty = dirty;
if (this.routeLocator instanceof RefreshableRouteLocator) {
((RefreshableRouteLocator) this.routeLocator).refresh();
}
}
}
(3)ZuulRefreshListener.reset
方法
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);
}
}
(4)发现ApplicationEvent
@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());
}
}
可以看到,其中的实例注册事件RoutesRefreshedEvent
和InstanceRegisteredEvent
均会触发刷新路由。
(5)Eureka触发路由更新
// org.springframework.cloud.netflix.eureka.CloudEurekaClient#onCacheRefreshed
@Override
protected void onCacheRefreshed() {
super.onCacheRefreshed();
if (this.cacheRefreshedCount != null) { // might be called during construction and
// will be null
long newCount = this.cacheRefreshedCount.incrementAndGet();
log.trace("onCacheRefreshed called with count: " + newCount);
this.publisher.publishEvent(new HeartbeatEvent(this, newCount));
}
}
@Override
// org.springframework.cloud.netflix.eureka.serviceregistry.EurekaAutoServiceRegistration#start
public void start() {
// only set the port if the nonSecurePort or securePort is 0 and this.port != 0
if (this.port.get() != 0) {
if (this.registration.getNonSecurePort() == 0) {
this.registration.setNonSecurePort(this.port.get());
}
if (this.registration.getSecurePort() == 0 && this.registration.isSecure()) {
this.registration.setSecurePort(this.port.get());
}
}
// only initialize if nonSecurePort is greater than 0 and it isn't already running
// because of containerPortInitializer below
if (!this.running.get() && this.registration.getNonSecurePort() > 0) {
this.serviceRegistry.register(this.registration);
this.context.publishEvent(new InstanceRegisteredEvent<>(this,
this.registration.getInstanceConfig()));
this.running.set(true);
}
}
版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/04/02/spring-cloud-zuul-routing-automatic-refresh-principle/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。
THE END
1
二维码
打赏
海报
Spring Cloud Zuul 路由自动刷新原理
现象
发布新服务,然后在数据库配置了路由,使用服务路径访问404。然后重新发布新的服务,就可以继续访问得到
(1)配置了路由第一次访问
(2)重新发布后访……
文章目录
关闭
共有 0 条评论