soul网关源码分析之代理请求源码深入分析

目标

分析背景

    上篇文章简单分析了下一个被soul网关代理的接口请求是如何被转发的,先来回顾一下,soul网关是通过实现Spring WebFlux提供的WebHandler接口,来实现对外提供Web服务,接收请求的;重写的handle方法来处理请求,处理请求时使用责任链模式来链式的执行插件,上篇是主要分析的一个代理Http 接口的处理流程, 所以就直接看了一遍执行Web请求的插件,也就是WebClientPlugin插件,本篇主要来看一下soul网关是如何匹配插件,比如如何匹配限流等等插件。

开始分析

  • 网关加载的插件

    根据下面的图可以看出来,我们自己搭建的网关一共加载了9个插件,虽然是9个插件,但其实时刻分类的,比如这里有两个带有Dubbo字样的插件,这其实是用来处理Dubbo的代理的,WebClientPlugin是HttpClient插件,BodyParamPlugin从名字上看像是处理某种body参数的插件,事实上它是用来处理代理接口为Dubbo接口的参数,等等。
在这里插入图片描述

  • Debug分析

    插件是按照顺序执行的,下面是具体插件的处理流程分析:

    • GlobalPlugin
  1. 步骤1和步骤2 是构造SoulContext的过程, 分别是使用DefaultSoulContextBuilder构造和通过reques.QueryParams()构造
  2. 步骤3 是设置将SoulContext设置到ServerWebExchangeattributes中,key是context

在这里插入图片描述

    • AbstractSoulPlugin(插件的父类)

    这里不得不插队说一下AbstractSoulPlugin,因为它是被定义成一个抽象方法并实现了SoulPlugin接口,后面的一些插件是继承了该抽象类的,它提供了一个模版方法execute,该方法实际上是重写的SoulPlugin接口方法,继承AbstractSoulPlugin类的插件类共用了AbstractSoulPlugin的模版方法execute,下面是AbstractSoulPlugin的代码和步骤分析:

  1. 从插件网关缓存的插件数据中根据插件名字获取到插件数据
  2. 根据插件名称获取到选择器列表,选择器数据就包括后端服务接口路径、权重、协议等信息
  3. 根据匹配策略获取到选择器数据,匹配器的策略目前分为And和Or两种
  4. 根据选择器Id获取到Rule数据列表,规则数据内容也包含一些路径,权重,协议等基本信息
  5. 根据匹配策略获取到具体的规则数据
  6. 然后执行继承AbstractSoulPlugin类的子类的doExecute方法
  7. 这里暂时不看匹配策略代码

在这里插入图片描述

    • RateLimiter(限流插件)
  1. 首先这个插件在我的程序中是没执行的,因为没有配置该插件,在webHandler,责任链处理逻辑是就skip掉了,但因为该插件排的靠前,就简单看一下代码逻辑
  2. 获取限流处理器Handle,这里不深入分析限流处理器
  3. 执行限流,是否被限流
  4. 如果不允许的话WebFluxResultUtils.result(exchange, error)处理返回结果,允许就继续执行插件链

在这里插入图片描述

    • DividePlugin插件
  1. 因为我们代理的是Http接口,并且这个所以我们已经打开了这个插件,可以看到该插件继承了AbstractSoulPlugin,所以执行了模版方法的所有逻辑
  2. 执行自己的doExecute方法,步骤1是从规则的handle数据中获取到插件的规则数据,包括超时配置、loadBalance算法名称、重试次数
  3. 执行LoadBalance
  4. 组装domain数据
  5. 组装realURL,就是真正的请求URL
  6. 将realURL、Timeout、retry数据初始化到ServerWebExchangeattributes
  7. 最后执行下一个插件

在这里插入图片描述

    • WebClientPlugin插件
  1. 这个插件的执行就不细说了,上篇文章的已经详细的讲到了,ServerWebExchangeattributes中已经记录了这个代理请求的协议时Http,所以WebClientPlugin插件不会被skip掉,总之这个插件的目的就是通过作为一个webclient请求后端被代理的接口

    • WebSocketPlugin插件
  1. 处理WebSocket的插件,被skip掉了,后面有机会再说

    • BodyParamPlugin插件
  1. 处理Dubbo协议body参数插件,被skip掉了,后面有机会再说

    • AlibabaDubboPlugin、DubboResponsePlugin插件
  1. 一个是处理Dubbo请求的插件,一个是处理Dubbo响应数据的插件,都被skip掉了,后面有机会再说

    • WebClientResponse插件
  1. 这是处理HttpResponse的插件
  2. ServerHttpResponse response = exchange.getResponse(); 获取后段接口响应
  3. ClientResponse clientResponse = exchange.getAttribute(Constants.CLIENT_RESPONSE_ATTR);获取ClientResponse
  4. 判断是否有响应还有响应的状态码,如果没有响应或者响应的状态码为超时,直接做出相应的响应
  5. 设置ClientResponse的响应数据,最后写入响应数据,这也是最后一个执行的插件,最后将数据返回到客户端

在这里插入图片描述

总结

    本篇内容实际上是对上一篇接收到请求后,具体的插件链处理的一个补充,不得不说soul网关的插件热插拔,插件调用的责任链设计模式,模版方法模式,策略模式等都是非常值得我们学习的,本篇文章在说明构造SoulContext数据时候没有深入,其实这里的soul上下文数据来源是MetaData数据的缓存,如果没有开启元数据,那么默认RpcType是Http,如果开启了元数据那么从元数据中匹配,具体是使用AntPathMatcher匹配ServerWebExchange中的URIpath

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Redick01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值