kong笔记 目录导航
本文通过一个自定义插件的编写,来了解Kong的插件机制
插件功能:

  • 原本返回百度首页,在添加插件之后,返回插件自定义的内容;

前提

  1. 使用kong代理百度的接口,配置route路径;
  2. 了解kong 插件的目录结构及部署(上一篇说到的)

实战

上一篇我们学到,一个插件必须包含两个文件:

  • handler.lua
  • schema.lua

handler.lua主要负责业务逻辑功能编写,schema.lua主要负责插件参数定制,类似将handler.lua中写死的变量抽出来写到schema.lua中,变为动态注入。

既然是自定义插件,又想应用到kong中,这期间肯定会有一些规范做适配,kong也不例外,在kong中,我们可以通过继承一个base插件:
kong.plugins.base_plugin

这个base插件提供了一些方法待实现,这些方法是基于 openresty的http模块来定义的

函数名 LUA-NGINX-MODULE Context 描述
:init_worker() init_worker_by_lua 在每个 Nginx 工作进程启动时执行
:certificate() ssl_certificate_by_lua 在SSL握手阶段的SSL证书服务阶段执行
:rewrite() rewrite_by_lua 从客户端接收作为重写阶段处理程序的每个请求执行。在这个阶段,无论是API还是消费者都没有被识别,因此这个处理器只在插件被配置为全局插件时执行
:access() access_by_lua 为客户的每一个请求而执行,并在它被代理到上游服务之前执行(路由)
:header_filter() header_filter_by_lua 从上游服务接收到所有响应头字节时执行
:body_filter() body_filter_by_lua 从上游服务接收的响应体的每个块时执行。由于响应流回客户端,它可以超过缓冲区大小,因此,如果响应较大,该方法可以被多次调用
:log() log_by_lua 当最后一个响应字节已经发送到客户端时执行

在各个阶段分别可以处理响应的业务。

另外,kong自身也提供了一些方法,有上下文的,有request、response等等的工具类,便于我们使用

PDK名称 功能描述
kong.client 提供客户端的ip, 端口等信息
kong.ctx 提供了插件之间共享并传递参数的桥梁
kong.ip 提供了kong.ip.is_trusted(address)IP白名单检测方法
kong.log 日志方法
kong.node 返回此插件的UUID信息
kong.request 提供request信息的读取功能,access()中可读
kong.response 提供response信息的读写功能, access()中不可用
kong.router 返回此请求关联的router信息
kong.service 返回此请求关联的service,可以动态修改后端服务信息
kong.service.request 仅用于access()方法中,可以读写请求信息
kong.service.response 仅可用于header_filter(), body_filter()方法中,只提供header信息的读取功能
kong.table kong提供的一套数据结构功能

更多方法参考:PDK - v2.5.x | Kong Docs (konghq.com)

插件代码

插件名称为:demo

  • handler.lua

    local BasePlugin = require "kong.plugins.base_plugin"local DemoHandler = BasePlugin:extend()DemoHandler.VERSION = "0.1.0"
    DemoHandler.PRIORITY = 2000-- 在 'init_by_lua_block' 中运行
    function DemoHandler:new()DemoHandler.super.new(self, "demo")
    end-- 在 'init_worker_by_lua_block' 中运行
    function DemoHandler:init_worker()DemoHandler.super.init_worker(self)
    end-- 在 'ssl_certificate_by_lua_block' 中运行
    function DemoHandler:certificate(conf)DemoHandler.super.certificate(self)
    end-- 在 'rewrite_by_lua_block' 中运行
    function DemoHandler:rewrite(conf)DemoHandler.super.rewrite(self)
    end-- 在 'access_by_lua_block' 中运行
    function DemoHandler:access(conf)DemoHandler.super.access(self)return kong.response.exit(200,conf.content)
    end-- 在 'header_filter_by_lua_block' 中运行
    function DemoHandler:header_filter(conf)DemoHandler.super.header_filter(self)
    end-- 在 'body_filter_by_lua_block' 中运行
    function DemoHandler:body_filter(conf)DemoHandler.super.body_filter(self)
    end-- 在 'log_by_lua_block' 中运行
    function DemoHandler:log(conf)DemoHandler.super.log(self)
    endreturn DemoHandler
    

    可以看到, 主要内容就是实现一个BasePlugin:extend(),实现一系统生命周期对应的方法后,返回这个实例即可.

    注意看一下 access()方法那块,我添加了一些内容!!!!

    而且, 所有方法在实现的时候, 都要先调用一下父类方法.

  • schema.lua

    return {no_consumer = true,fields = {content = { type = "string", default = "success!!" },}
    }
    

部署

  1. 先把代码放置到/opt/share/kong/plugins/demo位置

  2. 修改/etc/kong/kong.conf文件,加载插件

    lua_package_path = /opt/share/?.lua;;
    plugins = bundled,demo
    
  3. 重启Kong服务: kong restart

验证

  1. 打开konga,可以看到插件的部署情况:

    底色是绿色的代表正在使用的插件!

  2. 添加插件

    在这里我需要说明一下,kong插件的作用域范围有4个

    • Consumer作用域

    • route作用域
      仅针对route配置起作用(一个route可以配置多个path,也就是说这个route下的所有path插件都生效,不是这个route的path不生效)

    • service作用域

      针对service配置起作用(一个service有多个route,只要是属于这个service下的route,插件都生效)

    • global作用域

      所有请求,插件都生效

    目前我们演示route作用域,其他感兴趣的自己可以尝试一下:

    • 添加插件

      参数详情:

    • 访问结果

拓展

上述的实战比较简单,相信你也可以顺利完成,接下来我来说几个参坑点吧

  1. lua库扫描以及引入第三方lua库

    • 在我们编写lua脚本的时候,可能需要引入其他的库(kong自身没有提供的库),这个时候当我们在handler.lua中require的时候,则需要在kong.conf配置untrusted_lua_sandbox_requires属性,例如:

      在handler.lua中

      local template = require "resty.template"
      local split = require "kong.tools.utils".split
      

      那么我们必须在kong.conf中配置

      untrusted_lua_sandbox_requires = resty.template, kong.tools.utils
      
    • 还有一种方案是,直接将自己写好的库跟handler.lua,schema.lua放到一个文件夹里面,然后通过下列方式来引入

      local xxx     = require "kong.plugins.插件名称.自己库的名称"
      

      例如:插件名称叫demo,自己写的库名称是redisUtil.lua,那么引入方式为:

      local redisUtil     = require "kong.plugins.demo.redisUtil"
      
  2. 部署中常见的问题
    在部署插件中我们可能会遇到这么几个问题“

    • plugin is in use but not enabled;

      这个是因为你之前配置了一个自定义插件,并在某种场合使用了该插件,后来由于某种原因,你下架了该自定义插件,重启kong后,就会报该错误;

      想解决很简单,在数据库plugins中删除使用添加该插件的节点

    • plugin is enabled but not installed;

      这个是因为你在kong.conf中配置了自定义插件(plugins = bundled,demo),没有配置lua源(lua_package_path = /opt/share/?.lua;;)

  3. 多个作用域插件的执行顺序

    在上文我们提到插件可以作用域在consumer,route,service,global

    当多个作用域的插件出现在一个场景时,他们的优先级法则为:一个插件相对于它所配置的实体数量越具体,它的优先级就越高。

    多次配置插件时的完整优先级顺序为:

    1. 在以下组合上配置的插件:route、service和consumer。(consumer表示请求必须经过身份验证)。
    2. 在route和consumer的组合上配置的插件。(consumer表示请求必须经过身份验证)。
    3. 在service和consumer的组合上配置的插件。(consumer表示请求必须经过身份验证)。
    4. 在route和service的组合上配置的插件。
    5. 在consumer上配置的插件。(consumer表示请求必须经过身份验证)。
    6. 在route上配置的插件。
    7. 在service上配置的插件。
    8. 配置为global运行的插件。

    示例:如果插件应用两次(具有不同的配置):对于service(插件配置 A)和对于consumer(插件配置 B),则验证此consumer身份的请求将运行插件配置 B 并忽略 A。但是,不验证此consumer身份的请求将回退到运行插件配置 A。请注意,如果禁用了配置 B(其标志设置为 ),则配置 A 将应用于与配置 B 匹配的请求。rate-limiting``enabled``false

    官网解释:Admin API - v2.7.x | Kong Docs (konghq.com)

  4. 多个插件的执行顺序

    当一个路径涉及到多个插件时,有时候后一个插件需要依赖前一个插件的数据,所以出现了优先级问题,这个时候你可以通过

    CustomHandler.PRIORITY = 10
    

    来设置你的插件优先级

    优先级越高,相对于其他插件的阶段(如:access()、:log()等),插件的阶段执行得越快。 已有捆绑插件的当前执行顺序为:

    插件 优先级
    pre-function +inf
    zipkin 100000
    ip-restriction 3000
    bot-detection 2500
    cors 25000
    jwt 1005
    oauth2 1004
    key-auth 1003
    ldap-auth 1002
    basic-auth 1001
    hmac-auth 1000
    request-size-limiting 951
    acl 950
    rate-limiting 901
    response-ratelimiting 900
    request-transformer 801
    response-transformer 800
    aws-lambda 750
    azure-functions 749
    prometheus 13
    http-log 12
    statsd 11
    datadog 10
    file-log 9
    udp-log 8
    tcp-log 7
    loggly 6
    syslog 4
    galileo 3
    request-termination 2
    correlation-id 1
    post-function -1000

kong笔记——自定义插件开发相关推荐

  1. kong笔记——自定义插件 目录及部署

    kong笔记 目录导航 简述 本文目标: 了解kong插件的基本信息 手动部署自定义插件 注意:本文不涉及自定义插件的开发,仅仅说明自定义插件的目录结构与部署方式 目录结构 基本插件模块 两个必须的文 ...

  2. kong笔记 目录导航

    官方文档 官方网站:https://konghq.com 官方文档:https://docs.konghq.com 项目地址:https://github.com/Kong/kong 中文文档:htt ...

  3. kong笔记——kong/konga的搭建

    kong笔记 目录导航 本篇及以后的此系列文章皆为实战篇 版本介绍(重点,重点,一定要观察版本,防止不兼容情况!!): kong 2.5.0 konga 0.14.9 pgsql 9.6 linux ...

  4. kong笔记——认识kong

    kong笔记 目录导航 背景 最近公司打算重构API网关,给定的硬性条件是支持lua脚本,kubernetes可部署,可解析lua,另外需要支持身份认证,IP黑白名单,限流,负载均衡等一些功能,为此, ...

  5. kong笔记——kong的权限认证插件选择参考

    kong笔记--目录导航 kong自身共提供了这么几个权限认证插件: basic auth; key auth; hmac auth; jwt auth; oauth2 auth 接下来来逐个介绍其特 ...

  6. kong笔记——Service、Route路由功能

    kong笔记 目录导航 在上两篇文章,我们主要介绍了kong的概念以及kong的部署,相信大家对kong已经有了基本认识,那么我们该如何使用它呢? kong的功能有许多,我们一个一个来,先从kong的 ...

  7. iOS学习笔记-自定义过渡动画

    代码地址如下: http://www.demodashi.com/demo/11678.html 这篇笔记翻译自raywenderlick网站的过渡动画的一篇文章,原文用的swift,由于考虑到swi ...

  8. MySQL学习笔记—自定义函数

    MySQL学习笔记-自定义函数 注释语法: MySQL服务器支持3种注释风格: 从'#'字符从行尾. 从'– '序列到行尾.请注意'– '(双破折号)注释风格要求第2个破折号后面至少跟一个空格符(例如 ...

  9. kong笔记——kong、nginx性能压测对比

    简述 kong笔记 目录导航 前面介绍了kong的基本使用以及相关原理,那么接下来,我们需要对kong的性能做一个简单的了解. 性能压测 测试环境 机器类别及IP地址 硬件配置 操作系统 软件配置 网 ...

最新文章

  1. java7特性_Java7特性中,abstract class和interf
  2. Linq之select子句
  3. ACM Fellow发文抨击「同行评审」作弊:有「门道」的作者带飞,垃圾论文也能轻松中顶会...
  4. Android开发日常笔记
  5. java如何写安卓接口文档_android、java制作sdk以及自动生成文档
  6. 女朋友拿走程序员的什么最不能忍?直到程序员看到这个,无法忍受!
  7. Python《多线程并发爬虫》
  8. Halcon模板匹配(基于相关性)
  9. MoneyRunner API汇总
  10. 这位辩手,你想试试线上语音 battle 么?
  11. Excel数据可视化表盘模板
  12. 再写轮播图——两张图切换,一张充当背景并且模糊,一张做展示图
  13. 北京内推 | 华为诺亚方舟实验室招聘计算机视觉研究实习生
  14. flink 时间语义、水位线(Watermark)、生成水位线、水位线的传递
  15. 2022-2027年中国苹果树种植行业市场全景评估及发展战略规划报告
  16. 表达式之谜---半斤(复合赋值表达式)
  17. Java算术右移和逻辑右移
  18. 1离线TiDB-Ansible 部署问题-总结
  19. 主存、辅存、内存、外存、存储器是什么?还傻傻分不清楚?看完这一篇就够了
  20. 万恶的ie8 hack问题

热门文章

  1. java求圆的周长、面积
  2. QT开发:ImgTool小工具—图片训练集扩充
  3. 74ls175四人抢答器电路图_如何使用74LS175芯片实现四人抢答器的设计
  4. 跨链技术——公证人机制
  5. 解决Electron Fiddle无法下载安装electron不同版本支持的问题 - Fiddle一直都是checking status
  6. Vectorworks 2022 mac(3D建模专用工具)v2022.SP3完美支持m1
  7. GIS坐标系统(二):地理坐标
  8. 基于阿里云直播实现视频推流(ffmpeg)/拉流(Django2.0)以及在线视频直播播放(支持http/https)功能
  9. java水果爆炸动画,这种水果叫炮弹果会爆炸?这是一起海关人员被媒体坑了的沙雕事件...
  10. ionic类似时间轴的实现