从0到1手写网关之网关插件链设计

  1. GatewayPlugin插件设计
  • 网关统一前缀
  • 开始方法
  • 结束方法
  • 网关名称
  • 是否支持插件
  • 插件的具体处理逻辑

图片

  1. AbstractGatewayPlugin封装插件共用逻辑
  • support() 是否支持还是交由具体差价做判断;
  • handle()方法判断插件支持能力,是自己处理,还是交给下一个插件处理。

图片

  1. DirectPlugin直连插件
  • 请求url包含插件名称,该插件就支持,可以执行。

图片

  • 具体处理逻辑是:为header添加信息,根据url直接发起http请求,包装返回结果。然后插件链继续向后面执行。

图片

  1. MidnightRpcPlugin支持RPC远程调用
  • 请求url包含插件名称,该插件就支持,可以执行。

图片

具体执行逻辑是:

  • 从请求路径获取服务名称;
  • 通过注册中心拿到所有活着的服务实例;
  • 负载均衡选择调用的服务;
  • 拿到请求的报文;
  • 通过webclient发送post请求;
  • 通过entity获取响应报文;
  • 组装响应报文;
  • 然后插件链继续向后面执行;

图片

  1. GatewayPluginChain网关插件链
  • 定义处理接口方法

图片

  1. DefaultGatewayPluginChain网关默认插件链
  • 构造器注入所有插件;
  • 在handle()方法中,使用Mono.defer()惰性处理。根据插件顺序从0依次往后执行。

图片

  1. GatewayWebHandler网关请求处理器
  • 注入所有插件和过滤器
  • 没有任何插件,返回mock对象;
  • 执行自定义的过滤器;
  • 由默认网关插件链开始执行各个插件。

图片

  1. GatewayFilter网关过滤器
  • 定义过滤器接口方法filter();

图片

  1. DemoFilter自定义网关过滤器
  • 输出请求头

图片

  1. GatewayWebFilter网关前置过滤器
  • 输出mock对象

图片

  1. GatewayPostWebFilter网关后置过滤器
  • 输出属性信息;

图片

  1. 测试
  • 启动注册中心;
  • 启动服务提供者;
  • 启动网关;

  • 测试直连请求,得到预期的返回结果。

图片

观察日志,执行顺序:webHandler入口请求->自定义过滤器->直连插件执行->网关后置过滤器

图片

  • 测试RPC调用,得到预期返回结果

图片

观察日志,执行顺序:webHandler入口请求->自定义过滤器->RPC插件执行->网关后置过滤器

图片

基于插件的设计(shenyu)更加灵活,可以接入各种rpc框架;基于filter的设计(spring cloud gateway)专门为spring cloud体系设计。

源码:https://github.com/midnight2104/midnight-gateway