Spring Cloud Zuul 精进 (4)

ZuulHandlerMapping 自身继承了AbstractUrlHandlerMapping,即通过url来查找对应的处理器。判断的核心逻辑在 lookupHandler方法中:

@Override protected Object lookupHandler(String urlPath, HttpServletRequest request) throws Exception { if (this.errorController != null && urlPath.equals(this.errorController.getErrorPath())) { return null; } //判断urlPath是否被忽略,如果忽略则返回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) { //调用父类,注册处理器,这里所有路径的处理器都是ZuulController registerHandler(route.getFullPath(), this.zuul); } } }

整体逻辑就是在路由加载的时候需要为每个路由指定处理器,因为Zuul不负责逻辑处理,所以它也没有对应的Controller可以使用,那怎么办呢,注册处理器的时候,使用的是ZuulController,是Controller的子类,对应的适配器是SimpleControllerHandlerAdapter,也就说每一个路由规则公共处理器都是ZuulController,这个处理器最终会调用ZuulServlet经过zuul定义的和自定义的拦截器。

上面还有一句:

Collection<Route> routes = this.routeLocator.getRoutes();

RouteLocator的作用是路由定位器,先看它有哪些实现类:

SimpleRouteLocator:主要加载配置文件的路由规则;

DiscoveryClientRouteLocator:服务发现的路由定位器,去注册中心如Eureka,Consul等拿到服务名称,以这样的方式/服务名称/**映射成路由规则;

CompositeRouteLocator:复合路由定位器,主要集成所有的路由定位器(如配置文件路由定位器,服务发现定位器,自定义路由定位器等)来路由定位;

RefreshableRouteLocator:路由刷新,只有实现了此接口的路由定位器才能被刷新。

从实现类的功能看路由定位器的作用就是区分当前从哪里加载路由进行注册。上面这几个实现类都实现了Ordered类,加载的顺序依照getOrder()数值大小来定。

至此我们已经把Zuul最核心的路由部分撸了一遍,从Spring MVC 加载Servlet 的过程入手,到自定义 ZuulServlet 进行处理,进而使用Zuul中定义的各种Filter来做逻辑过滤。原理其实很简单,重要的是思想。作为一个网关,它是很重要的服务,这种实现方式大家觉得是否优雅,是否还有别的实现方式呢?如果是你你会如何实现网关,这些问题大家可以慢慢思考。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgzsdw.html