1.引入依赖,在启动类中添加@EnableZuulProxy,声明这是一个Zuul代理。
    2.注册到Eureka Server,启动服务,访问这个端口,url中带上要请求的服务名。
    //开启断路器(hystrix)
    @EnableCircuitBreaker
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Import(ZuulProxyMarkerConfiguration.class)
    public @interface EnableZuulProxy {

    }

    org.springframework.cloud.netflix.zuul.ZuulProxyMarkerConfiguration
    //让ZuulProxyMarkerConfiguration 配置生效
    @Configuration
    public class ZuulProxyMarkerConfiguration {
    //创建Marker 实例,让ZuulProxyMarkerConfiguration 配置生效
    @Bean
    public Marker zuulProxyMarkerBean() {
    return new Marker();
    }

    class Marker {

    }

    }
    05.原理解析 - 图1
    org.springframework.cloud.netflix.zuul.ZuulProxyAutoConfiguration的父类是
    org.springframework.cloud.netflix.zuul.ZuulServerAutoConfiguration

    org.springframework.boot.web.servlet.ServletRegistrationBean

    //注册一个zuulServlet
    @Bean
    @ConditionalOnMissingBean(name = “zuulServlet”)
    @ConditionalOnProperty(name = “zuul.use-filter”, havingValue = “false”, matchIfMissing = true)
    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;
    }
    //注册一个zuulServletFilter
    @Bean
    @ConditionalOnMissingBean(name = “zuulServletFilter”)
    @ConditionalOnProperty(name = “zuul.use-filter”, havingValue = “true”, matchIfMissing = false)
    public FilterRegistrationBean zuulServletFilter() {
    final FilterRegistrationBean filterRegistration = new FilterRegistrationBean<>();
    filterRegistration.setUrlPatterns(
    Collections.singleton(this.zuulProperties.getServletPattern()));
    filterRegistration.setFilter(new ZuulServletFilter());
    filterRegistration.setOrder(Ordered.LOWESTPRECEDENCE);
    // The whole point of exposing this servlet is to provide a route that doesn’t
    // buffer requests.
    filterRegistration.addInitParameter(“buffer-requests”, “false”);
    return filterRegistration;
    }


    Zuulfilter 有四种 pre(前置),route(路由定位),post(执行后),error(出错),执行流程如上图,执行代码如下面
    05.原理解析 - 图2
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    try {
    this.init((HttpServletRequest)servletRequest, (HttpServletResponse)servletResponse);
    RequestContext context = RequestContext.getCurrentContext();
    context.setZuulEngineRan();

    try {
    //执行前置过滤器
    this.preRoute();
    } catch (ZuulException var12) {
    //实现前置过滤器出错,则执行出错过滤器
    this.error(var12);
    //执行后置过滤
    this.postRoute();
    return;
    }

    try {
    this.route();
    } catch (ZuulException var13) {
    this.error(var13);
    this.postRoute();
    return;
    }

    try {
    this.postRoute();
    } catch (ZuulException var11) {
    this.error(var11);
    }
    } catch (Throwable var14) {
    this.error(new ZuulException(var14, 500, “UNHANDLED_EXCEPTION
    “ + var14.getClass().getName()));
    } finally {
    RequestContext.getCurrentContext().unset();
    }
    }

    不管是哪一种过滤器,最后都会落到
    com.netflix.zuul.FilterProcessor#runFilters
    public Object runFilters(String sType) throws Throwable {
    if(RequestContext.getCurrentContext().debugRouting()) {
    Debug.addRoutingDebug(“Invoking {“ + sType + “} type filters”);
    }

    boolean bResult = false;
    //据filter类型,获取排过序的filter
    List list = FilterLoader.getInstance().getFiltersByType(sType);
    if(list != null) {
    for(int i = 0; i < list.size(); ++i) {
    //处理filter执行
    ZuulFilter zuulFilter = (ZuulFilter)list.get(i);
    Object result = this.processZuulFilter(zuulFilter);
    if(result != null && result instanceof Boolean) {
    bResult |= ((Boolean)result).booleanValue();
    }
    }
    }

    return Boolean.valueOf(bResult);
    }


    public Object processZuulFilter(ZuulFilter filter) throws ZuulException {
    RequestContext ctx = RequestContext.getCurrentContext();
    boolean bDebug = ctx.debugRouting();
    String metricPrefix = “zuul.filter-“;
    long execTime = 0L;
    String filterName = “”;

    try {
    long ltime = System.currentTimeMillis();
    filterName = filter.getClass().getSimpleName();
    RequestContext copy = null;
    Object o = null;
    Throwable t = null;
    if(bDebug) {
    Debug.addRoutingDebug(“Filter “ + filter.filterType() + “ “ + filter.filterOrder() + “ “ + filterName);
    copy = ctx.copy();
    }
    //真正执行ZuulFilter内存方法
    ZuulFilterResult result = filter.runFilter();
    ExecutionStatus s = result.getStatus();
    execTime = System.currentTimeMillis() - ltime;
    switch(null.$SwitchMap$com$netflix$zuul$ExecutionStatus[s.ordinal()]) {
    case 1:
    t = result.getException();
    ctx.addFilterExecutionSummary(filterName, ExecutionStatus.FAILED.name(), execTime);
    break;
    case 2:
    o = result.getResult();
    ctx.addFilterExecutionSummary(filterName, ExecutionStatus.SUCCESS.name(), execTime);
    if(bDebug) {
    Debug.addRoutingDebug(“Filter {“ + filterName + “ TYPE:” + filter.filterType() + “ ORDER:” + filter.filterOrder() + “} Execution time = “ + execTime + “ms”);
    Debug.compareContextState(filterName, copy);
    }
    }

    if(t != null) {
    throw t;
    } else {
    this.usageNotifier.notify(filter, s);
    return o;
    }
    } catch (Throwable var15) {
    if(bDebug) {
    Debug.addRoutingDebug(“Running Filter failed “ + filterName + “ type:” + filter.filterType() + “ order:” + filter.filterOrder() + “ “ + var15.getMessage());
    }

    this.usageNotifier.notify(filter, ExecutionStatus.FAILED);
    if(var15 instanceof ZuulException) {
    throw (ZuulException)var15;
    } else {
    ZuulException ex = new ZuulException(var15, “Filter threw Exception”, 500, filter.filterType() + “:” + filterName);
    ctx.addFilterExecutionSummary(filterName, ExecutionStatus.FAILED.name(), execTime);
    throw ex;
    }
    }
    }

    com.netflix.zuul.ZuulFilter#runFilter
    public ZuulFilterResult runFilter() {
    ZuulFilterResult zr = new ZuulFilterResult();
    if (!isFilterDisabled()) {
    if (shouldFilter()) {
    Tracer t = TracerFactory.instance().startMicroTracer(“ZUUL::” + this.getClass().getSimpleName());
    try {
    //执行,run方法就是具体filter 实现的run方法
    Object res = run();
    zr = new ZuulFilterResult(res, ExecutionStatus.SUCCESS);
    } catch (Throwable e) {
    t.setName(“ZUUL::” + this.getClass().getSimpleName() + “ failed”);
    zr = new ZuulFilterResult(ExecutionStatus.FAILED);
    zr.setException(e);
    } finally {
    t.stopAndLog();
    }
    } else {
    zr = new ZuulFilterResult(ExecutionStatus.SKIPPED);
    }
    }
    return zr;
    }