热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

浅谈SpringCloud之zuul源码解析

这篇文章主要介绍了浅谈SpringCloud之zuul源码解析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

zuul各版本实现存在一些微小的变化,总的实现思想未改变,以spring-cloud-netflix-core-1.3.6.RELEASE为例

一、zuul的重要的初始化类

org.springframework.cloud.netflix.zuul.ZuulServerAutoConfiguration

org.springframework.cloud.netflix.zuul.ZuulProxyAutoConfiguration

org.springframework.cloud.netflix.zuul.ZuulFilterInitializer

org.springframework.cloud.netflix.zuul.RibbonCommandFactoryConfiguration

ZuulServerAutoConfiguration

初始化路由规则

初始化一些重要的filter如 PreDecorationFilter,RibbonRoutingFilter

初始化ZuulFilterInitializer

初始化ZuulHandlerMapping

代码如下

 //路由规则
  @Bean
 @ConditionalOnMissingBean(DiscoveryClientRouteLocator.class)
 public DiscoveryClientRouteLocator discoveryRouteLocator() {
 return new DiscoveryClientRouteLocator(this.server.getServletPrefix(), this.discovery, this.zuulProperties,
  this.serviceRouteMapper);
 }
   
 // pre filters
 @Bean
 public PreDecorationFilter preDecorationFilter(RouteLocator routeLocator, ProxyRequestHelper proxyRequestHelper) {
 return new PreDecorationFilter(routeLocator, this.server.getServletPrefix(), this.zuulProperties,
  proxyRequestHelper);
 }

 // route filters
 @Bean
 public RibbonRoutingFilter ribbonRoutingFilter(ProxyRequestHelper helper,
  RibbonCommandFactory<&#63;> ribbonCommandFactory) {
 RibbonRoutingFilter filter = new RibbonRoutingFilter(helper, ribbonCommandFactory, this.requestCustomizers);
 return filter;
 }

  @Configuration
 protected static class ZuulFilterConfiguration {

 @Autowired
 private Map filters;

 @Bean
 public ZuulFilterInitializer zuulFilterInitializer(
  CounterFactory counterFactory, TracerFactory tracerFactory) {
  FilterLoader filterLoader = FilterLoader.getInstance();
  FilterRegistry filterRegistry = FilterRegistry.instance();
  return new ZuulFilterInitializer(this.filters, counterFactory, tracerFactory, filterLoader, filterRegistry);
 }

 }
 @Bean
 public ZuulController zuulController() {
 return new ZuulController();
 }

 @Bean
 public ZuulHandlerMapping zuulHandlerMapping(RouteLocator routes) {
 ZuulHandlerMapping mapping = new ZuulHandlerMapping(routes, zuulController());
 mapping.setErrorController(this.errorController);
 return mapping;
 }

ZuulProxyAutoConfiguration

zuulProxAutoConfiguration继承ZuulServerAutoConfiguration功能上和zuulServerAutoConfiguration

主要功能是增加了RibbonCommandFactoryConfiguration的配置,初始化所有的实现ribbon的方式如apache,okhttp。

ZuulFilterInitializer

该类的作用主要是把初始化的过滤器注册到zuul的FilterRegistry,FilterRegistry是一个单例用于初始化路由信息,在ZuulRunner中使用

RibbonCommandFactoryConfiguration

  主要作用是配置转发的实现,实现主要有apache,okhttp

二、zuul的转发实现

首先第一步转到ZuulHandlerMapping中的lookupHandler方法,把转发转到zuulController中

@Override
 protected Object lookupHandler(String urlPath, HttpServletRequest request) throws Exception {
 if (this.errorController != null && urlPath.equals(this.errorController.getErrorPath())) {
  return null;
 }
 String[] ignored = this.routeLocator.getIgnoredPaths().toArray(new String[0]);
 if (PatternMatchUtils.simpleMatch(ignored, urlPath)) {
  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);
 }

第一次访问时dirty为true会初始化一次请求规则如下

private void registerHandlers() {
 Collection 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);
  }
 }
 }

第二步ZuulController继承ServletWrappingController的会把请求转到ZuulServlet中如下

/**
 * @author Spencer Gibb
 */
public class ZuulController extends ServletWrappingController {
 public ZuulController() {
 setServletClass(ZuulServlet.class);
 setServletName("zuul");
 setSupportedMethods((String[]) null); // Allow all
 }

 @Override
 public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
 try {
  // We don't care about the other features of the base class, just want to
  // handle the request
  return super.handleRequestInternal(request, response);
 }
 finally {
  // @see com.netflix.zuul.context.ContextLifecycleFilter.doFilter
  RequestContext.getCurrentContext().unset();
 }
 }
}

第三步ZuulServlet的service方法如下主要执行pre,route,postRoute三种路由器

 @Override
  public void service(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse) throws ServletException, IOException {
    try {
      init((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse);
      // Marks this request as having passed through the "Zuul engine", as opposed to servlets
      // explicitly bound in web.xml, for which requests will not have the same data attached
      RequestContext cOntext= RequestContext.getCurrentContext();
      context.setZuulEngineRan();
      try {
        preRoute();
      } catch (ZuulException e) {
        error(e);
        postRoute();
        return;
      }
      try {
        route();
      } catch (ZuulException e) {
        error(e);
        postRoute();
        return;
      }
      try {
        postRoute();
      } catch (ZuulException e) {
        error(e);
        return;
      }
    } catch (Throwable e) {
      error(new ZuulException(e, 500, "UNHANDLED_EXCEPTION_" + e.getClass().getName()));
    } finally {
      RequestContext.getCurrentContext().unset();
    }
  }

四、最后由SendResponseFilter执行返回结果,filterOrder为1000所以最好post的filter不要超过1000否则影响返回结果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 本文介绍了多种Eclipse插件,包括XML Schema Infoset Model (XSD)、Graphical Editing Framework (GEF)、Eclipse Modeling Framework (EMF)等,涵盖了从Web开发到图形界面编辑的多个方面。 ... [详细]
  • 华为云openEuler环境下的Web应用部署实践
    本文详细记录了在华为云openEuler系统上进行Web应用部署的具体步骤,包括配置yum源、安装Apache、MariaDB、PHP及其相关组件,并完成WordPress的安装与配置过程。 ... [详细]
  • BeautifulSoup4 是一个功能强大的HTML和XML解析库,它能够帮助开发者轻松地从网页中提取信息。本文将介绍BeautifulSoup4的基本功能、安装方法、与其他解析工具的对比以及简单的使用示例。 ... [详细]
  • 本文介绍了在解决Hive表中复杂数据结构平铺化问题后,如何通过创建视图来准确计算广告日志的曝光PV,特别是针对用户对应多个标签的情况。同时,详细探讨了UDF的使用方法及其在实际项目中的应用。 ... [详细]
  • 近期在研究Java IO流技术时,遇到了一个关于如何正确读取Doc文档而不出现乱码的问题。本文将详细介绍使用Apache POI库处理Doc和Docx文件的具体方法,包括必要的库引入和示例代码。 ... [详细]
  • 详解MyBatis二级缓存的启用与配置
    本文深入探讨了MyBatis二级缓存的启用方法及其配置细节,通过具体的代码实例进行说明,有助于开发者更好地理解和应用这一特性,提升应用程序的性能。 ... [详细]
  • SpringBoot底层注解用法及原理
    2.1、组件添加1、Configuration基本使用Full模式与Lite模式示例最佳实战配置类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断配置类组 ... [详细]
  • 本文探讨了在SharePoint环境中使用BDC(Business Data Catalog)时遇到的问题及其解决策略,包括XML文件导入SSP后的不可见性问题以及与远程SQL Server 2005连接的难题。 ... [详细]
  • MyBatis入门指南:环境搭建与基础配置详解
    本文详细介绍了MyBatis的基础配置流程,包括在Maven项目中添加MyBatis依赖、IDEA中配置数据库连接、导入SQL脚本以及编写mybatis-config.xml配置文件等关键步骤。 ... [详细]
  • 浅谈Android五大布局——LinearLayout、FrameLayout和AbsoulteLa
    为什么80%的码农都做不了架构师?Android的界面是有布局和组件协同完成的,布局好比是建筑里的框架,而组件则相当于建筑里的砖瓦。 ... [详细]
  • 本文详细介绍了在PHP中如何获取和处理HTTP头部信息,包括通过cURL获取请求头信息、使用header函数发送响应头以及获取客户端HTTP头部的方法。同时,还探讨了PHP中$_SERVER变量的使用,以获取客户端和服务器的相关信息。 ... [详细]
  • 本文探讨了在使用 MyBatis 进行批量数据处理时遇到的参数绑定异常问题,并提供了详细的解决方案。 ... [详细]
  • 使用 ModelAttribute 实现页面数据自动填充
    本文介绍了如何利用 Spring MVC 中的 ModelAttribute 注解,在页面跳转后自动填充表单数据。主要探讨了两种实现方法及其背后的原理。 ... [详细]
  • 本文档提供了在Windows 10操作系统中安装Python 3及Scrapy框架的完整指南,包括必要的依赖库如wheel、lxml、pyOpenSSL、Twisted和pywin32的安装方法。 ... [详细]
  • Maven快照版本管理及更新策略详解
    本文深入探讨了Maven中的快照版本管理和更新策略,解释了快照版本与正式版本的区别,并提供了如何配置快照更新策略的方法,以确保项目依赖始终保持最新。 ... [详细]
author-avatar
猥琐叔装嫩小孩
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有