spring-cloud 源码 zuul 启动(一)

 

zuul 网关启动源码分析

 

1 依赖配置

依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>

启动

@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy //启动zuul代理,@EnableZuulServer 非代理方式启动
public class ZuulApplication {
    final static Logger logger = LoggerFactory.getLogger(ZuulApplication.class);


    public static void main(String[] args) {
        ConfigurableApplicationContext applicationContext = new SpringApplicationBuilder(ZuulApplication.class)
                .web(true).run(args);
        logger.debug(applicationContext.getId() + "已经启动,当前host:{}",
                applicationContext.getEnvironment().getProperty("HOSTNAME"));
    }

}

2 自动启动配置入口过程

按springboot 源码分析的老套路从启动注解@EnableZuulProxy 开始

/**
 * Sets up a Zuul server endpoint and installs some reverse proxy filters in it, so it can
 * forward requests to backend servers. The backends can be registered manually through
 * configuration or via DiscoveryClient.
 *
 * @see EnableZuulServer for how to get a Zuul server without any proxying

@EnableCircuitBreaker //开启断路器(hystrix)
@EnableDiscoveryClient
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(ZuulProxyMarkerConfiguration.class)
public @interface EnableZuulProxy {
}
//让ZuulProxyMarkerConfiguration 配置生效
@Configuration
public class ZuulProxyMarkerConfiguration {
    //创建Marker 实例,让ZuulProxyMarkerConfiguration 配置生效
    @Bean
    public Marker zuulProxyMarkerBean() {
        return new Marker();
    }

    class Marker {
    }
}

//zuul代理配置
@Configuration
//引用创建下面三种客户端配置
@Import({ RibbonCommandFactoryConfiguration.RestClientRibbonConfiguration.class,
        RibbonCommandFactoryConfiguration.OkHttpRibbonConfiguration.class,
        RibbonCommandFactoryConfiguration.HttpClientRibbonConfiguration.class })
//Marker 实例存在,该配置类生效
@ConditionalOnBean(ZuulProxyMarkerConfiguration.Marker.class)
public class ZuulProxyAutoConfiguration extends ZuulServerAutoConfiguration {
//省出一大波呆码
}

3 ZuulServerAutoConfiguration 代理配置详解

从上面可以看到ZuulProxyAutoConfiguration 继承ZuulServerAutoConfiguration 那么在这里先分析ZuulServerAutoConfiguration

    //zuul 配置属性类,如路由等信息
    @Autowired
    protected ZuulProperties zuulProperties;

    @Autowired
    protected ServerProperties server;

    //请求错误控制器
    @Autowired(required = false)
    private ErrorController errorController;

    //省去一些代码

    //组合路由定位器,将个种路由定位器进行组合
    @Bean
    @Primary
    public CompositeRouteLocator primaryRouteLocator(
            Collection<RouteLocator> routeLocators) {
        return new CompositeRouteLocator(routeLocators);
    }

    //简单路由定位器,作用于uri与服务地址的匹配
    @Bean
    @ConditionalOnMissingBean(SimpleRouteLocator.class)
    public SimpleRouteLocator simpleRouteLocator() {
        return new SimpleRouteLocator(this.server.getServletPrefix(),
                this.zuulProperties);
    }

    //关网控制器,会被ZuulServlet(跟DispatchServlet类似) 通过handlerAdapter找到并被调用
    @Bean
    public ZuulController zuulController() {
        return new ZuulController();
    }

    //HandlerMapping 一个实现,这块完全是spring-mvc的东西
    @Bean
    public ZuulHandlerMapping zuulHandlerMapping(RouteLocator routes) {
        ZuulHandlerMapping mapping = new ZuulHandlerMapping(routes, zuulController());
        mapping.setErrorController(this.errorController);
        return mapping;
    }

    @Bean
    public ApplicationListener<ApplicationEvent> zuulRefreshRoutesListener() {
        return new ZuulServerAutoConfiguration.ZuulRefreshListener();
    }

    //如果zuulServlet 不存在存执行
    @Bean
    @ConditionalOnMissingBean(name = "zuulServlet")
    public ServletRegistrationBean zuulServlet() {
        ServletRegistrationBean servlet = new ServletRegistrationBean(new ZuulServlet(),
                this.zuulProperties.getServletPattern());
        // The whole point of exposing this servlet is to provide a route that doesn't
        // buffer requests.
        servlet.addInitParameter("buffer-requests", "false");
        return servlet;
    }

    //实例化一个前置zuulfilter 
    @Bean
    public ServletDetectionFilter servletDetectionFilter() {
        return new ServletDetectionFilter();
    }

    //下面省去一波代码,主要是各中zuulfilter

4 ZuulProxyAutoConfiguration 代理配置详解

 //ribbon个性化参数设置
    @SuppressWarnings("rawtypes")
    @Autowired(required = false)
    private List<RibbonRequestCustomizer> requestCustomizers = Collections.emptyList();

    //服务发布客户端
    @Autowired
    private DiscoveryClient discovery;

    //服务路由匹配器
    @Autowired
    private ServiceRouteMapper serviceRouteMapper;

    //省去一点代码

    //注入封装了服务发现客户端各路由定位器及其它一些信息
    @Bean
    @ConditionalOnMissingBean(DiscoveryClientRouteLocator.class)
    public DiscoveryClientRouteLocator discoveryRouteLocator() {
        return new DiscoveryClientRouteLocator(this.server.getServletPrefix(), this.discovery, this.zuulProperties,
                this.serviceRouteMapper);
    }

    //zuul 前置过滤器
    @Bean
    public PreDecorationFilter preDecorationFilter(RouteLocator routeLocator, ProxyRequestHelper proxyRequestHelper) {
        return new PreDecorationFilter(routeLocator, this.server.getServletPrefix(), this.zuulProperties,
                proxyRequestHelper);
    }

    // ribbon 路由过滤器,如果是使用serviceId请求服务执行该过滤器
    @Bean
    public RibbonRoutingFilter ribbonRoutingFilter(ProxyRequestHelper helper,
                                                   RibbonCommandFactory<?> ribbonCommandFactory) {
        RibbonRoutingFilter filter = new RibbonRoutingFilter(helper, ribbonCommandFactory, this.requestCustomizers);
        return filter;
    }

    // 主机地址路由器,如果发现是主要地址请求,帽执行该路由器
    @Bean
    @ConditionalOnMissingBean(SimpleHostRoutingFilter.class)
    public SimpleHostRoutingFilter simpleHostRoutingFilter(ProxyRequestHelper helper, ZuulProperties zuulProperties) {
        return new SimpleHostRoutingFilter(helper, zuulProperties);
    }

   //省去一堆代码

到这里,以上是zuul 启动的基本过程,一下编将会分析zuul请求的执行过程

    原文作者:Spring Boot
    原文地址: https://blog.csdn.net/yangyangiud/article/details/80490366
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞