Spring Cloud Zuul【源码篇】zuul如何进行请求转发、限流熔断等功能扩展

本文详细介绍了Spring Cloud Zuul的过滤链执行顺序,包括pre、route、post route三个阶段的过滤器,如ServletDetectionFilter、RibbonRoutingFilter等,并探讨了如何扩展Zuul以支持Hystrix熔断功能,以及在Zuul中集成Hystrix的实现方式。
摘要由CSDN通过智能技术生成

参考资料:
Spring Cloud 官网
Zuul wiki

相关版本:zuul 1.3.1,spring boot 2.1.4 ,spring cloud Greenwich.SR1

回顾

Spring Cloud Zuul【源码篇】揭秘 Zuul 中知道了 Zuul 本质是由 Servlet 和 Filter 组成。

其中 Servlet 用来接收请求,而 ZuulFilter 则对请求进行包装以及处理,如:请求转发,客户端负载均衡,熔断等。

Zuul 过滤链执行顺序

Zuul 提供了一些 ZuulFilter ,有的用来做请求封装,有的用来处理请求。
这些 ZuulFilter 各自有各自的作用,并且存在执行顺序。为了规范 ZuulFilter 的执行,Zuul 针对 ZuulFilter 的执行顺序进行了如下定义

  • 根据 pre、route、 post route 进行区分。
    pre 优先级最高。
    route 优先级次之。
    post route 优先级最低。

  • 根据上面的区分之后,每个类别中又有给的优先级。

验证 ZuulFilter 执行顺序

根据 pre、route、 post route 进行区分

查看源码 ZuulServlet#service 能够知道 ZuulFilter 根据类型 pre -> route -> post 优先级由高到低以此执行过滤操作。

public class ZuulServlet extends HttpServlet {
   
    public void service(......){
   
        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;
        }
    }
}

Netflix 官方文档中,给定了一张图片同样说明了根据类型的执行顺序

在这里插入图片描述

根据 order执行顺序

根据类型(pre、route、post) 分类执行之后,每一个分类有各自的执行顺序排列,排列参数: filterOrder 。数字越小,优先级越高。

Zuul 1.3.1 版本中 默认提供的 ZuulFilter

pre filters

过滤类 优先级(越小越优先)
ServletDetectionFilter -3
Servlet30WrapperFilter -2
FormBodyWrapperFilter -1
DebugFilter 1
PreDecorationFilter 5

route filters

过滤类 优先级(越小越优先)
RibbonRoutingFilter 10
SimpleHostRoutingFilter 100
SendForwardFilter 500

post filters

过滤类 优先级(越小越优先)
SendErrorFilter 0
SendResponseFilter 1000

Zuul 1.3.1 版本提供的 ZuulFilter 功能简介

  • 在 Zuul 中所有的 Filter 都需要继承 ZuulFilter。
  • 默认 ZuulFilter 是否启用有两个判断条件 1、zuul.{FilterCLass}.{FilterType}.disable :false 开启,true 关闭 2、ZuulFilter#shouldFilter 方法,返回 true 执行,返回 false 不执行
  • ZuulFilter 判定成功之后执行 ZuulFilter#run() 方法

pre filter

ServletDetectionFilter

ZuulFilter 执行触发条件

public class ServletDetectionFilter extends ZuulFilter {
   
    // 拦截所有请求
    public boolean shouldFilter() {
    return true; }
}

只要该过滤器开启,拦截所有请求进行过滤处理。

过滤执行逻辑

public class ServletDetectionFilter extends ZuulFilter {
   
    @Override
    public Object run() {
   
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        if (!(request instanceof HttpServletRequestWrapper)
                && isDispatcherServletRequest(request)) {
   
            ctx.set(IS_DISPATCHER_SERVLET_REQUEST_KEY, true);
        }
        else {
   
            ctx.set(IS_DISPATCHER_SERVLET_REQUEST_KEY, false);
        }

        return null;
    }
    private boolean isDispatcherServletRequest(HttpServletRequest request) {
   
        return request.getAttribute(
                DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null;
    }
}

代码逻辑简单明了:判定请求来源是不是 DispatcherServlet。并将判断结果作为参数存入 RequestContext中。

扩展:在 Spring MVC 中,在请求进入到 DispatcherServlet 中时,所有的标签会被打上标签:DispatcherServlet.class.getName() + “.CONTEXT”

Servlet30WrapperFilter

ZuulFilter 执行触发条件

public class Servlet30WrapperFilter extends ZuulFilter {
   
    // 拦截所有请求
    public boolean shouldFilter() {
   
        return true; // TODO: only if in servlet 3.0 env
    }
}

只要该过滤器开启,拦截所有请求进行过滤处理。

过滤执行逻辑

public class Servlet30WrapperFilter extends ZuulFilter {
   
    @Override
    public Object run() {
   
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        if (request instanceof HttpServletRequestWrapper) {
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值