zuul框架设计与实现

1、概述

zuul是基于spring mvc实现的。过滤器有

 其中标黑的过滤器在使用@EnableZuulProxy才开始,其他在@EnableZuulProxy和EnableZuulServer开启

2、接口设计 

2.1 Filter

在ZuulHandlerMapping中注册了ZuulController,其中ZuulController处理是通过ZuulServlet来处理的,在启动时会通过FilterRegistry来加载ZuulFilter.

2.2  路由

主要是Route和RouteLocator,其结构为

 RouteLocator:根据请求url得到Route

RefreshableRouteLocator:支持更新路由

SimpleRouteLocator:RouteLocator的实现类

CompoisteRouteLocator:RefreshableRouteLocator的实现类,内部包括RouteLocator的列表,使用了组合模式

2.3 动态路由

动态路由与ZuulRefreshListener相关,其是spring事件类型的监听器。

	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);
		}

	}

其支持的事件类型有

  • ContextRefreshedEvent
  • RefreshScopeRefreshedEvent
  • RouteRefreshedEvent
  • InstanceRegisteredEvent
  • ParentHeartbeatEvent
  • HeartbeatEvent

事件发生时,会将ZuulHandlerMapping的dirty标识设置为true。ZuulHandlerMapping在根据url及请求查找对应的Handler时,会判断dirty标识,如果为true,会通过RouteLocator获取所有路由重新注册到Mapping中。

protected Object lookupHandler(String urlPath, HttpServletRequest request)
		throws Exception {
	if (this.errorController != null
			&& urlPath.equals(this.errorController.getErrorPath())) {
		return null;
	}
	if (isIgnoredPath(urlPath, this.routeLocator.getIgnoredPaths())) {
		return null;
	}
	RequestContext ctx = RequestContext.getCurrentContext();
	if (ctx.containsKey("forward.to")) {
		return null;
	}
	if (this.dirty) {
		synchronized (this) {
			if (this.dirty) {
				registerHandlers();
				this.dirty = false;
			}
		}
	}
	return super.lookupHandler(urlPath, request);
}

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);
		}
	}
}

参考资料:

https://github.com/Netflix/zuul

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值