Apache APISIX ext-plugin-post-resp 插件:在响应阶段运行外部插件(External Plugin Runner)的完整实践指南 Apache APISIX ext-plugin-post-resp 插件在响应阶段运行外部插件External Plugin Runner的完整实践指南【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisixext-plugin-post-resp是 Apache APISIX 中用于在请求获得上游响应之后、将响应交还给客户端之前调度外部插件External Plugin执行的官方插件。它依托 Plugin Runner进程外插件运行器机制让开发者可以用 Go、Java、Python 等非 Lua 语言编写的插件处理并改写上游返回的状态码、响应头和响应体。阅读本文后你将掌握该插件的执行时机、完整配置属性、启用与删除方式、降级策略以及其底层基于 Unix Socket 的 RPC 通信原理。一、功能概述与执行时机ext-plugin-post-resp的核心定位是在请求从上游upstream拿到响应之后执行配置好的外部插件并允许这些插件影响当前请求的最终响应。官方文档明确提示外部插件的执行会影响当前请求的响应结果文档原文。与之相对的是ext-plugin-pre-req插件后者在请求阶段rewrite 阶段执行外部插件用于改写请求本身。二者共同构成 APISIX 在请求前、响应后两个关键节点上挂载外部插件能力的基础设施。从源码实现看apisix/plugins/ext-plugin-post-resp.lua 中该插件的定义如下local name ext-plugin-post-resp local _M { version 0.1, priority -4000, name name, schema ext.schema, }priority -4000意味着它在所有插件中属于极低优先级从而保证在正常请求/响应流程完成之后才介入处理符合响应后处理的语义。插件通过before_proxy钩子完成响应获取、RPC 调用与响应回写源码。二、工作原理从上游取响应到 Plugin Runner 的 RPC 调用要理解ext-plugin-post-resp需要先理解外部插件External Plugin与插件运行器Plugin Runner的概念APISIX 将外部插件作为子进程sidecar运行这些子进程被称为 Plugin Runner外部插件文档。ext-plugin-post-resp的完整执行链路如下依据 apisix/plugins/ext-plugin-post-resp.lua 源码建立上游连接并取回响应get_response函数使用lua-resty-http库local http require(resty.http)直接与 APISIX 已选中的上游节点ctx.picked_server.host/port建立 TCP 连接携带原始请求的方法、路径、查询参数、请求头和请求体发起请求得到响应对象res。发送响应调用 RPC将上游响应状态码 响应头通过ext.communicate(conf, ctx, name, constants.RPC_HTTP_RESP_CALL)发给 Plugin Runner其中RPC_HTTP_RESP_CALL即响应阶段调用的 RPC 类型见 apisix/constants.lua 中定义的RPC_PREPARE_CONF1、RPC_HTTP_REQ_CALL2、RPC_EXTRA_INFO3、RPC_HTTP_RESP_CALL4。外部插件返回结果Plugin Runner 执行外部插件后返回状态码code和响应体body。若body非空说明外部插件改写了响应体直接以返回的code、body作为最终响应返回源码。回写原始响应若外部插件未改动响应体则send_response会通过ngx.print/ngx.flush将上游响应体分块写给客户端同时应用外部插件可能修改的状态码源码。通信本身基于Unix Socket FlatBuffers 二进制协议APISIX 与 Plugin Runner 之间按1 字节类型 3 字节大端长度 数据体的帧格式收发消息并支持通过RPC_EXTRA_INFO交互式地按需传递请求/响应变量、请求体、响应体等额外信息详见 apisix/plugins/ext-plugin/init.lua 的send/receive与handle_extra_info。值得注意的实现细节是ext-plugin-post-resp 是通过 APISIX 主动向上游再发起一次 HTTP 请求来获取响应内容而非直接复用 Nginx 内置的代理响应流这正是文档中该插件使用 lua-resty-http 库向上游发送请求文档原文的技术背景。三、属性Attributes说明插件仅有两个配置属性官方文档给出的属性表如下NameTypeRequiredDefaultValid valuesDescriptionconfarrayFalse[{name: ext-plugin-A, value: {enable:feature}}]List of Plugins and their configurations to be executed on the Plugin Runner.allow_degradationbooleanFalsefalseSets Plugin degradation when the Plugin Runner is not available. When set totrue, requests are allowed to continue.结合 apisix/plugins/ext-plugin/init.lua 中的 JSON Schema 定义可以补充更多校验细节conf类型为数组minItems 1至少配置一个外部插件。每个元素为对象必填字段为name与valuename外部插件名字符串minLength 1、maxLength 128value传给该外部插件的配置字符串类型典型用法是传入一段 JSON 字符串如{enable:feature}。Plugin Runner 会收到这些 name/value 对并据此加载并初始化对应的外部插件。allow_degradation布尔值默认false。控制当 Plugin Runner 不可用时是否允许降级放行详见下文降级策略小节。四、配置 Plugin Runner在启用ext-plugin-*插件之前必须先在conf/config.yaml中配置 Plugin Runner 的启动命令外部插件文档ext-plugin: cmd: [blah] # 替换为所选 Runner 的实际可执行文件例如 Go Runner 的二进制路径APISIX 会将 Runner 作为自己的子进程管理重启或 reload APISIX 时Runner 也会随之重启Runner 意外退出后 APISIX 会等待 3 秒自动重新拉起源码 的setup_runner与重试逻辑。开发调试阶段可以通过环境变量APISIX_LISTEN_ADDRESS让 Runner 监听固定地址并在 APISIX 配置中通过path_for_test指向它从而无需重启 APISIX 即可单独重启 RunnerAPISIX_LISTEN_ADDRESSunix:/tmp/x.sock ./the_runnerext-plugin: # cmd: [blah] # 开发模式不要配置可执行文件 path_for_test: /tmp/x.sock # 不带 unix: 前缀生产环境不应使用path_for_testUnix Socket 路径会由 APISIX 动态生成默认形如./conf/apisix-master_pid.sock见 apisix/plugins/ext-plugin/helper.lua 的get_path。五、启用插件以下示例在一条 Route 上启用ext-plugin-post-resp插件并配置一个名为ext-plugin-A的外部插件文档原文。首先可从conf/config.yaml中取出admin_key并保存为环境变量admin_key$(yq .deployment.admin.admin_key[0].key conf/config.yaml | sed s///g)然后通过 Admin API 创建/更新路由curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H X-API-KEY: $admin_key -X PUT -d { uri: /index.html, plugins: { ext-plugin-post-resp: { conf : [ {name: ext-plugin-A, value: {\enable\:\feature\}} ] } }, upstream: { type: roundrobin, nodes: { 127.0.0.1:1980: 1 } } }说明Admin API 默认监听9180端口/apisix/admin/routes/1表示创建 ID 为 1 的路由conf中的每一项对应一个要执行的外部插件及其配置请求到达该路由后APISIX 会向上游127.0.0.1:1980发请求并把拿到的响应交给 Plugin Runner 中的ext-plugin-A处理。六、示例使用与验证配置完成后直接请求网关即可触发外部插件执行文档原文curl -i http://127.0.0.1:9080/index.html请求会到达已配置的 Plugin Runnerext-plugin-A随即被执行。仓库中的测试用例 t/plugin/ext-plugin/response.t 验证了该插件在响应阶段的能力矩阵修改响应体modify_body true时上游返回的hello world被外部插件改写为cat客户端最终收到200与改写后的响应体TEST 3修改响应头modify_header true时外部插件设置X-Runner: Test-Runner等响应头TEST 4同一响应头出现多次时会以逗号合并TEST 5X-Same: one, two修改状态码modify_status true时外部插件将状态码改为304TEST 6。此外t/plugin/ext-plugin/extra-info.t 中同样包含基于ext-plugin-post-resp的用例TEST 6验证外部插件按需读取请求变量、请求体与响应体等附加信息的 RPC 交互路径。七、降级策略allow_degradation当 Plugin Runner 不可用进程未启动、Socket 连接失败、RPC 返回错误等时插件默认会让请求失败。从 apisix/plugins/ext-plugin/init.lua 的communicate实现可以看到完整逻辑每次调用最多重试3 次如果错误是conf token not found配置令牌缓存失效会先刷新缓存再重试若重试后仍失败allow_degradation false默认返回503请求失败allow_degradation true打印Plugin Runner is wrong, allow degradation警告后直接放行请求继续正常处理响应不再经过外部插件。在 Route 上启用降级的配置示例{ uri: /index.html, plugins: { ext-plugin-post-resp: { allow_degradation: true, conf: [ {name: ext-plugin-A, value: {\enable\:\feature\}} ] } }, upstream: { type: roundrobin, nodes: { 127.0.0.1:1980: 1 } } }降级模式适合将外部插件视为尽力而为增强能力的场景Runner 故障时宁可牺牲插件功能也要保证业务请求不中断。对应地t/plugin/ext-plugin/response.t 中的 TEST 7 及后续用例专门覆盖了allow_degradation默认值及降级行为。八、与其他插件的兼容性限制由于ext-plugin-post-resp使用lua-resty-http自行向上游发起请求文档原文以下能力无法与它同时使用proxy-control控制代理行为的插件proxy-mirror请求镜像插件proxy-cache代理缓存插件APISIX 与上游之间的 mTLSAPISIX 与上游的 mTLS暂不支持。原因在于上述插件依赖 Nginx 内置的代理/缓存管线而ext-plugin-post-resp绕开了这条管线、改由 Lua 层的 HTTP 客户端直接访问上游因此相关能力无法生效。在规划使用该插件时应避免在同一条路由上同时配置上述插件。另外需要留意外部插件的执行会直接影响当前请求的响应文档中以:::note特别提示因此建议仅在确实需要对响应做二次加工的场景如响应体脱敏、响应头注入、灰度标记、内容改写中使用。九、删除插件移除ext-plugin-post-resp插件只需把 Route 配置中的plugins字段删掉即可APISIX 会自动热加载生效无需重启文档原文curl http://127.0.0.1:9180/apisix/admin/routes/1 -H X-API-KEY: $admin_key -X PUT -d { uri: /index.html, upstream: { type: roundrobin, nodes: { 127.0.0.1:1980: 1 } } }删除后请求将直接按正常代理流程转发不再触发 Plugin Runner 的响应阶段 RPC 调用。十、小结ext-plugin-post-resp是 APISIX 外部插件体系在响应方向上的关键一环它以极低优先级在请求获得上游响应后介入通过 Unix Socket 与进程外的 Plugin Runner 通信让 Go、Java、Python、JavaScript 等语言编写的插件能够改写响应状态码、响应头与响应体。配套的allow_degradation属性提供了 Runner 故障时的优雅降级能力。建议在路由规划时注意其与 proxy-control / proxy-mirror / proxy-cache 及上游 mTLS 的兼容性边界并参考 外部插件文档 与仓库测试用例 t/plugin/ext-plugin/response.t 理解其行为细节。【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisix创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考