apisix-插件开发

APISix-插件开发

源码下载:git clone https://github.com/apache/apisix.git

apisix目录结构如下

apisix-2.0/
├── admin/                    # 管理接口相关模块
│   ├── d_api_router.lua      # API 路由定义
│   ├── d_balancer.lua        # 负载均衡器定义
│   └── ...                   # 其他管理接口相关文件
├── balancer/                 # 负载均衡相关模块
│   ├── d_api_router.lua      # API 路由定义
│   ├── d_balancer.lua        # 负载均衡器定义
│   └── ...                   # 其他负载均衡相关文件
├── core/                     # 核心功能模块
│   ├── d_api_router.lua      # API 路由定义
│   ├── d_balancer.lua        # 负载均衡器定义
│   └── ...                   # 其他核心功能相关文件
├── discovery/                # 服务发现相关模块
│   ├── d_api_router.lua      # API 路由定义
│   ├── d_balancer.lua        # 负载均衡器定义
│   └── ...                   # 其他服务发现相关文件
├── http/                     # HTTP 处理相关模块
│   ├── d_api_router.lua      # API 路由定义
│   ├── d_balancer.lua        # 负载均衡器定义
│   └── ...                   # 其他HTTP处理相关文件
├── plugins/                  # 插件相关模块
│   ├── d_api_router.lua      # API 路由定义
│   ├── d_balancer.lua        # 负载均衡器定义
│   └── ...                   # 其他插件相关文件
├── ssl/                      # SSL/TLS 相关模块
│   ├── d_api_router.lua      # API 路由定义
│   ├── d_balancer.lua        # 负载均衡器定义
│   └── ...                   # 其他SSL/TLS相关文件
├── stream/                   # 流处理相关模块
│   ├── d_api_router.lua      # API 路由定义
│   ├── d_balancer.lua        # 负载均衡器定义
│   └── ...                   # 其他流处理相关文件
├── utils/                    # 工具函数模块
│   ├── d_api_router.lua      # API 路由定义
│   ├── d_balancer.lua        # 负载均衡器定义
│   └── ...                   # 其他工具函数相关文件
├── CHANGELOG.md              # 版本变更日志
├── LICENSE                   # 软件许可证
├── Makefile                  # 构建脚本
└── version                   # 版本信息文件

插件开发参考案例

参考文件路径:apisix/apisix/plugins

参考文件: echo.luaexample-plugin.lua

具体实现步骤:复制 example-plugin.lua,另起一个名字plugin-test.lua

编码:

local ngx = ngx
local core = require("apisix.core")
local plugin = require("apisix.plugin")
local upstream = require("apisix.upstream")

-- 定义用于配置校验的 schema。
local schema = {
    type = "object",
}

-- 定义插件名称。
local plugin_name = "plugin-test"

local _M = {
    version = 0.1,
    priority = 11111,
    name = plugin_name,
    schema = schema,
}

-- 检查插件配置是否符合 schema 。
function _M.check_schema(conf, schema_type)
    return core.schema.check(schema, conf)
end

-- 插件初始化时调用。
-- 通常用于设置必要的状态或初始化资源。
function _M.init()
    -- 在这里编写初始化代码(例如,设置计时器,初始化缓存)
end

-- 插件被移除或重新加载时调用。
-- 用于清理资源,比如关闭连接或释放缓存。
function _M.destroy()
    -- 在这里编写清理代码(例如,关闭连接,释放内存)
end

-- rewrite 阶段函数,在 access 阶段之前调用。
-- 通常用于修改请求。
function _M.rewrite(conf, ctx)
    -- URL 重写或请求修改的代码
end

-- access 阶段函数,在请求代理到上游之前调用。
-- 用于实现访问控制、认证与授权。
function _M.access(conf, ctx)
    -- 在这里编写访问控制的代码(例如,验证令牌,限流)
end

-- log 阶段函数,在请求完成后调用。
-- 用于记录请求和响应的详细信息。
function _M.log(conf, ctx)
    -- 在这里编写日志记录的代码(例如,将请求详细信息记录到日志文件)
end

return _M

apisix 插件生命周期

  1. init:插件初始化时调用,用于设置必要的状态或进行一次性资源初始化。
  2. check_schema:检查插件的配置是否符合预定义的 schema,以确保配置正确性。
  3. rewrite:在请求到达后端之前进行 URL 重写或请求参数修改,以适应业务需求。
  4. access:执行访问控制和认证授权,确保请求的合法性,包括速率限制和安全策略。
  5. before_proxy:在请求代理至上游之前执行,用于处理与代理请求相关的最后阶段设置。
  6. header_filter:修改响应头,通常用于添加自定义头信息或对返回头进行过滤。
  7. body_filter:处理并可能修改响应体内容,例如数据过滤、压缩或编码转换。
  8. log:在请求完成后记录请求和响应相关的信息,用于监控、审计和调试。

注意事项

开发插件目录, /apisix/apisix/plugins/
如果只开发一个lua文件, 则直接放在此目录即可
如果有文件夹的添加, 需要修改 Makefile 文件, 编译一下
参考: https://apisix.apache.org/zh/docs/apisix/plugin-develop/#插件命名,优先级和其他

实战

给所有的请求添加一个请求头:

第一步 修改基本属性

修改插件基本属性,名称,版本,优先级(数字越高越先执行)

local schema = {
    type = "object",
}

local plugin_name = "plugin-test"

local _M = {
    version = 0.1,
    priority = 11111,
    name = plugin_name,
    -- 定义插件配置的结构和数据约束
    schema = schema,
}

第二步 开发

添加请求头, 可以在rewrite阶段就可以完成, 所以代码如下
log阶段打印所有的请求头

function _M.rewrite(conf, ctx)
    core.request.set_header(ctx, "plugin-header", "hello")
end


function _M.log(conf, ctx)
    local headers = ngx.req.get_headers()
    core.log.warn("headers: ", core.json.encode(headers))
end

第三步 添加插件

目录: /apisix/conf/config-default.yaml

添加位置: plugins:

重新启动apisix

变量介绍

ctx: 是apisix为每个请求提供的上下文对象,用于存储和传递与当前请求相关的信息和状态,具体而言包括以下几点:

  • 请求的信息: ctx中包含了所有与当前请求相关的信息,比如客户端请求的路径,参数,方法等
  • 插件状态:每个插件可以在ctx中存储和操作相关的数据,这意味着不同插件可以通过ctx共享数据
  • 生命周期持续:由于ctx存在于整个请求的生命周期中,不同阶段的插件方法都可以访问相同的ctx,从而保持一致的数据状态。

方法介绍

获取所有的请求头, table数据类型

local headers = ngx.req.get_headers()

添加请求头

core.request.set_header(ctx, "key", "value")

获取单独请求头

local time = core.request.header(ctx, key)

获取请求体

core.request.get_body()

获取响应头

local value = ngx.header[key]

添加响应头

ngx.header[key] = value

获取响应体

local body = ngx.arg[1]
posted @ 2025-04-10 21:52  小郑[努力版]  阅读(152)  评论(0)    收藏  举报