专栏首页posluaKong 插件加载机制概述

Kong 插件加载机制概述

概述

插件可以认为是 Kong 管理 API 的核心,其模块化和可扩张性做得很好,尤其是其灵活的加载机制使得 Kong 能够针对不同 API 启用、组合任意插件。Kong 默认自带的插件集,按照功能的不同大致可以分为六大类:Authentication 认证、Security 安全、Traffic Control 流量控制、Analytics & Monitoring 分析监控、Transformations 请求报文处理、Logging 日志等

无论是为了理解这些插件的工作原理,亦或者是定制开发属于自己的插件,熟悉插件的加载机制无疑都是一个关键的前提。

Kong 从 0.11.0 版本开始区分了社区版和商业版,节点之间的消息通信也改为了数据库轮训机制(原先是通过 serf 实现的),通过最终一致性实现了节点的无状态,任何时候节点只需连上数据库即可工作。之前的版本都相对来说太重,部署过于复杂。所以我这里将基于 Kong 0.12.3 版本分析其插件加载机制。

我一般研究一门新技术,倾向于研究更新更早期的代码。 因为非常成熟有名的代码往往已经过度设计,对于阅读代码入门不一定是好的选择。而一些出于项目早期的代码,倒是更容易阅读理解其核心原理。


1. 插件的应用方式

Kong 按照插件的不同应用方式,大致可以分为两大类四小类

  • 全局插件 → GLOBAL 既不独自应用于 API,又不独自应用于 Consumer 的插件,而是应用于所有 API 和 Consumer 的插件。
  • 局部插件 → LOCAL
    • 仅仅应用于 API 的插件 → api
      1. 应用于 API 且指定 Consumer 的插件 → api & consumer 特定用户且特定 API 需要执行的插件。这个貌似不太好理解,我这里来举个例子: 假设现在有两个 API: /foo, /bar; 两个 Consumer: c1, c2 如果想让 c1 在调用 /foo 时启用插件 rate-limit,这里只需要为 /foo 添加 rate-limit 插件并指定 c1 Consumer 即可。 这里并不能单独为 c1 配置 consumer 插件,因为这样会使 c1 消费 /bar 时也调用 rate-limit 插件,显然是不符合需求的。
      2. 应用于 API 的插件
    • 应用于 Consumer 的插件 → consumer

这四种方式插件的组合将伴随在 API 请求响应生命周期不同阶段中逐个被执行。同时 Kong 也将严格约束这四种方式在启用插件时的行为。比如:同一种方式只能添加同一个插件一次、不同方式之间可以添加同一个插件

2. 插件的生效策略

所谓生效策略就是 Kong 组织上述提到的四种不同的插件应用方式的策略。结果是:API 最终要执行的插件等于 LOCAL 插件和 GLOBAL 插件的并集。也就是说:

API 最终要运行的插件 = api & consumer + consumer + api + GLOBAL = LOCAL + GLOBAL

但是这里还有一个问题没有解决,就是虽然在同一种方式上同一插件只能应用一次,但是由于有上述四种不同的插件应用方式的存在。那么完全可能有同一插件在不同方式上均应用的情况,比如:rate-limit 插件既应用于 consumer 上,又应用于 api 上,那么这时候哪个生效?

答案是:consumer 上的 rate-limit 生效。Kong 在处理上述四种方式插件冲突的优先级是:

注意:这里并不是插件的执行顺序,而是处理插件冲突的优先级

3. 插件的执行顺序

插件的执行顺序由插件自身的优先级唯一确定(既和插件应用的四种方式无关,也无关于插件的生效策略),其并不会随 API 的不同而改变。待确定插件执行的顺序之后,插件将随着 API 请求响应生命周期中的不同阶段逐个执行其相应的 hook

上图并不能视为插件的执行顺序,而是请求生命周期不同阶段的执行顺序,这里可以理解为插件的执行阶段。在不同的阶段中,插件均需按顺序执行其对应的 hook

值得一提的是,目前 Kong 默认自带的插件均运行在 access 以及之后的阶段。

4. 一个请求的一生

当一个请求在自己生命周期的不同阶段时,均需要按顺序(自身的优先级)遍历所有已安装插件(包括自己自定义的),以检查自己是否被启用(属于 GLOBAL 插件或者是 LOCAL 插件),并执行其对应的 hook。我把它称之为 「phase 循环」。

理解「phase 循环」对于掌握 Kong 插件机制至关重要!比如:

  • rewrite 循环 当一个请求进入到 rewrite 阶段时,所有已安装插件(包括自己自定义的)将会按照顺序(自身的优先级)检查自己是否属于 GLOBAL 插件。如果属于则执行其 rewrite 方法,否则检查下一个插件,直到检查完全部插件为止。
  • access 循环 接下来进入到 access 阶段,在这个阶段将完成插件生效策略的筛选。同样所有已安装插件继续按照顺序(当然还是自身的优先级)检查自己是否属于 api 插件,如果属于并且恰巧还是 auth 插件(auth 插件拥有较高的优先级执行都比较早),那么接下来将依次检查自己是否属于 api & consumerconsumerapiGLOBAL 插件并执行其 access 方法;否则将直接检查自己是否属于 apiGLOBAL 插件。
  • filter 循环 经过上面两个阶段之后,就已经完成了插件生效策略的筛选。当前请求应该被执行的插件已经确定,并被缓存在自身中,并随着生命周期的结束而被销毁。当然这是一步很重的操作。不过也从这个阶段开始,Kong 在遍历所有插件时将直接从上面的缓存中查找,并执行相应的 filter 方法,而不再经过生效策略的筛选,这当然也是出于性能上的考量。

结语

通过理解上面概念,我现在来回答这个终极问题:到底是 LOCAL 插件先被执行,还是 GLOBAL 插件先被执行?

答案是:乱序的。因为插件的执行顺序由插件自身的优先级唯一确定。注意这里需要和插件的生效策略区分开来,后者的生效顺序总是 LOCAL 优先于 GLOBAL

我曾经和 Kong 的技术人员聊过,他说目前社区反映 Kong 在长时间运行之后,内存碎片严重,我相信这里少不了插件的生效策略的锅。

本文分享自微信公众号 - poslua(poslua)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-05-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 常用的数据库管理系统软件有哪些?

    目前互联网中比较常用的数据库管理系统有SYBASE、DB2、ORACLE、MySQL、ACCESS、Visual Foxpro、MS SQL Server、In...

    chenzhouliyan
  • Access-SQL手工注入实战

    经过反复尝试,这里可以利用“+”替换空格和大写字母绕过WTS-WAF,并且此waf没有过滤and。

    HACK学习
  • nginx禁止用户访问.htaccess

    .htaccess文件(或者”分布式配置文件”)提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其...

    php007
  • shiro实战之常见问题整理

    在调用subject.login时会调用UserRealm的doGetAuthenticationInfo方法。

    开发架构二三事
  • Spring Repository解析---以Mongo Repository为例

    Spring 为java web 开发领域提供了大量的优秀的框架,第三方包,大大解放了生产力,本文主要介绍Spring Repository在连接数据库这边做的...

    方丈的寺院
  • 移动端接口安全那些事

    服务端提供对外开放到公网API接口,危险非常大.尤其对移动应用开放接口的时候,更需要关注接口安全性的问题,要确保应用APP与API之间的安全通信,防止数据被恶意...

    php007
  • 脚本错误量极致优化-监控上报与Script error

    脚本错误主要有两类:语法错误、运行时错误。监控的方式主要有两种:try-catch、window.onerror。

    张炳
  • 使用Guava的RateLimiter做限流

    1.在日常生活中,我们肯定收到过不少不少这样的短信,“京东最新优惠卷…”,“天猫送您…”。这种类型的短信是属于推广性质的短信。这种短信一般群发量会到千万级别。然...

    哲洛不闹
  • Windows认证及抓密码总结

    windows的认证方式主要有NTLM认证、Kerberos认证两种。同时,Windows Access Token记录着某用户的SID、组ID、Session...

    HACK学习
  • Springboot 配置多数据源Mybatis的MapUnderScoreToCamelCase不生效

    本文是一篇问题解决经验分享的文章。因为在网上没有搜到相关的介绍文章,而在遇到这个问题的解决过程中,犯过一些想当然的错误,所以记录在此,希望能够对后面遇到此问题的...

    方丈的寺院

扫码关注云+社区

领取腾讯云代金券