SpringCloud-Zuul(二):自定义Filter及内部路由源码解析

原创地址,jsbintask的博客(食用效果最佳),转载请注明出处!java

前言

上一篇介绍了SpringCloud使用Zuul的调用流程,明白了Zuul的工做原理关键在于ZuulServlet和它的内置Filter,因此在实际工做中,编写业务逻辑的关键就在于自定义filter。spring

用法

实现ZuulFilter

实现一个自定义Filter很简单,继承自ZuulFilter便可:api

@Component
public class Filter extends ZuulFilter {
    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext context = RequestContext.getCurrentContext().getRequest();
        HttpServletRequest request = context.getRequest();
        HttpServletResponse response = context.getResponse();
        System.out.println("Filter.run");
        return null;
    }
}
复制代码
  1. filterType方法返回filter类型
  2. filterOrder返回同类型filter执行顺序
  3. shouldFilter返回请求是否应该执行run方法。
  4. run表示业务逻辑执行过程。
  5. 处理逻辑过程当中若是须要用到HttpServletRequest和HttpServletResponse能够用RequestContext.getCurrentContext()拿出。

Filter类型

Zuul的Filter一共分为四个种类,Pre,Route,Post,Error,每种Filter的执行时机不一样,因此他们在业务逻辑功能上有所不一样,如图: app

Zuul

  1. Pre类型的Filter老是先执行,它能够作限流,权限控制等。
  2. Route类型的Filter为Zuul内部转发请求到真正的服务的Filter,通常咱们不须要实现这种类型.
  3. Post为请求转发完成后的后续动做,能够进行日志等的一些添加。
  4. Error为上述Filter出错后执行的动做,能够进行错误处理等。 关于它们的执行顺序,如图:
    Zuul

源码解析

zuul内部已经定义了各类类型的filter,如预处理,路由转发,错误处理等。咱们能够经过源码来研究Zuul是如何帮咱们转发请求的: 负载均衡

Zuul

  1. RibbonRoutingFilter
  2. SimpleHostRoutingFilter
  3. SendForwardFilter 上面三个Filter只会执行一个,控制它们执行过程的为PreDecorationFilter:
    Zuul
    当整合的是微服务时,则配置的为服务名,如:
zuul:
 prefix: /api
 routes:
 espay-auth:
 path: /test/**
 service-id: service-name
复制代码

这个时候将调用RibbonRoutingFilter做负载均衡转发请求:ide

protected ClientHttpResponse forward(RibbonCommandContext context) throws Exception {
    Map<String, Object> info = this.helper.debug(context.getMethod(),
            context.getUri(), context.getHeaders(), context.getParams(),
            context.getRequestEntity());

    RibbonCommand command = this.ribbonCommandFactory.create(context);
    try {
        ClientHttpResponse response = command.execute();
        this.helper.appendDebug(info, response.getRawStatusCode(), response.getHeaders());
        return response;
    }
    catch (HystrixRuntimeException ex) {
        return handleException(info, ex);
    }
}
复制代码

而当咱们配置的直接为某个地址:微服务

zuul:
 routes:
 espay-auth:
 path: /auth/**
 url: http://baidu.com
复制代码

则会调用SimpleHostRoutingFilter进行转发,它内部直接使用HttpClient进行转发: post

Zuul
而当请求出错时,则会交由 SendErrorFilter处理,它会设置标志位 SEND_ERROR_FILTER_RAN为true,而后从新发送请求到 PreDecorationFilter。这个时候的流程为:
Zuul
SendForwardFilter:
Zuul
这样一次完整的路由,转发,错误处理就分析完毕。

总结

  1. Zuul内部使用自定义filter处理业务逻辑。
  2. Zuul内部有四种不一样类型的Filter。
  3. Zuul内部转发请求有两种,为服务下边的RibbonRoutingFilter,普通http转发的SimpleHostRoutingFilter.

关注我,这里只有干货!this

相关文章: SpringCloud-Zuul(一):技术选型及请求流程源码走读url

相关文章
相关标签/搜索