Apache APISIX External Plugin 外部插件与 Plugin Runner 开发接入全指南
API网关后端云原生微服务【免费下载链接】apisixThe Cloud-Native API Gateway and AI Gateway项目地址https://gitcode.com/gh_mirrors/api/apisix点击查看免费下载导读本指南围绕 Apache APISIX 的External Plugin外部插件与Plugin Runner插件运行器机制展开讲解为什么需要它、它是如何工作的、如何实现、如何在生产与开发两种场景下配置以及常见问题的解决方案。读完本文你将掌握用 Java / Go / Python / JavaScript 等任意语言编写 APISIX 插件并接入运行的方法、ext-plugin-pre-req/ext-plugin-post-req/ext-plugin-post-resp三个外部插件入口的使用方式以及 Plugin Runner 进程生命周期管理、RPC 通信协议和降级degradation等底层原理可直接基于当前仓库落地实践。什么是 External Plugin 与 Plugin RunnerAPISIX 原生使用 Lua 语言编写插件这类插件在 APISIX 进程内部直接执行性能好、开发快。但在很多真实场景中团队可能希望复用已有的 Java / Go / Python / JavaScript 技术栈与生态而不是学习 Lua。为此APISIX 提供了一种Sidecar 模式APISIX 以子进程的方式加载并运行一个独立的进程这个进程就是Plugin Runner而由开发者用其他语言编写的、运行在 Runner 进程内的插件称为External Plugin外部插件。关键概念对应关系如下概念说明External Plugin由开发者用非 Lua 语言如 Java / Go / Python / JS编写的插件运行在独立的 Plugin Runner 进程中Plugin RunnerAPISIX 以子进程Sidecar方式管理的独立进程负责接收 APISIX 发来的 RPC 请求、执行外部插件并返回结果ext-plugin-*APISIX 侧用于把请求转发给 Plugin Runner 的内置插件包括ext-plugin-pre-req、ext-plugin-post-req、ext-plugin-post-resp三个在 APISIX 的路由配置中ext-plugin-*插件与其他任何 APISIX 插件一样可以被动态启用、禁用和重新配置无需重启 APISIX。从源码看这三个插件共享同一套 schema 与通信逻辑ext-plugin-pre-req.luapriority 12000在rewrite阶段执行请求处理调用RPC_HTTP_REQ_CALLext-plugin-post-req.luapriority -3000在access阶段执行请求处理同样是RPC_HTTP_REQ_CALLext-plugin-post-resp.luapriority -4000在before_proxy阶段执行响应处理调用RPC_HTTP_RESP_CALL。三个插件共用的 schema 定义在 apisix/plugins/ext-plugin/init.lualocal schema { type object, properties { conf { type array, items { type object, properties { name { type string, maxLength 128, minLength 1 }, value { type string, }, }, required {name, value} }, minItems 1, }, allow_degradation {type boolean, default false} }, }也就是说每个ext-plugin-*插件可以携带一个conf数组插件名称与参数键值对用于告诉 Plugin Runner 该调用哪些外部插件及传入哪些配置以及可选的allow_degradation允许降级默认为false。它是如何工作的整体工作流程如下在 APISIX 的config.yaml中配置ext-plugin.cmdAPISIX 将以此命令以子进程方式启动 Plugin Runner该子进程与 APISIX 主进程运行在同一系统用户下当 APISIX 重启或 reload 时Plugin Runner 也会随之重启当你为某个路由配置了ext-plugin-*插件后匹配该路由的请求会触发一次从 APISIX 到 Plugin Runner 的 RPC 调用Plugin Runner 收到 RPC 调用后在自身进程内构造一个请求上下文依次执行所配置的外部插件最后把处理结果返回给 APISIX外部插件及其执行顺序由ext-plugin-*插件中的conf数组决定且可以像普通插件一样动态调整。进程管理与守护逻辑从 apisix/plugins/ext-plugin/init.lua 的源码可以看到 Runner 进程的完整管理机制启动_M.init_worker()在privileged agent进程中读取ext-plugin.cmd配置若存在则调用setup_runner(cmd)通过ngx_pipe.spawn启动子进程见 init.lua 第 986-1005 行环境变量注入启动前会强制设置两个环境变量——APISIX_CONF_EXPIRE_TIME配置令牌过期时间与APISIX_LISTEN_ADDRESSUnix Socket 监听地址见 spawn_proc守护重启Runner 异常退出后setup_runner会通过runner:wait()捕获退出事件向events_list广播runner_exit事件触发配置令牌缓存清理并在3 秒后自动重新拉起Runner见 init.lua 第 936-983 行退出清理_M.exit_worker()在退出阶段对 Runner 先发送SIGTERM并调用core.os.waitpid(pid, 1)等待 1 秒让其清理资源随后由 GC 终结器兜底发送SIGKILL见 init.lua 第 1008-1022 行。底层 RPC 通信协议APISIX 与 Plugin Runner 之间通过Unix Domain Socket 自定义二进制帧 FlatBuffers 序列化进行 RPC 通信核心实现集中在 apisix/plugins/ext-plugin/init.lua 与 apisix/plugins/ext-plugin/helper.lua。帧格式每个消息包由 4 字节头部 数据体组成。首字节为 RPC 类型如RPC_PREPARE_CONF、RPC_HTTP_REQ_CALL、RPC_HTTP_RESP_CALL、RPC_EXTRA_INFO、RPC_ERROR后 3 字节为大端序的长度字段最大单包数据长度为2^24 - 1。发送与接收分别由send与receive函数实现见 init.lua 第 128-208 行。连接管理每个 worker 与 Runner 建立 TCP socket 连接settimeouts(1000, 60000, 60000)通信完成后调用setkeepalive(180 * 1000, 32)将连接放回连接池复用见 rpc_call。关键 RPC 流程RPC_PREPARE_CONF配置准备当某个路由首次命中ext-plugin-*时APISIX 会向 Runner 发送该请求对应的插件配置conf数组Runner 校验后返回一个conf token。token 会被缓存在ext-plugin共享字典shared dict与 Lua 侧 lrucache 中默认缓存 3600 秒见 helper.lua 的 get_conf_token_cache_time后续请求直接携带 token 而无需重复全量下发配置RPC_HTTP_REQ_CALL请求调用APISIX 将请求的 URI、args、headers、method、源 IP 等打包发送给 RunnerRunner 运行外部插件后返回动作结果。动作类型包括Stop直接终止请求由 APISIX 返回插件指定的状态码与响应体状态码缺省时默认 200Rewrite修改请求的 path、headers、query args甚至替换请求体RespHeaders直接改写响应头。RPC_EXTRA_INFO附加信息拉取Runner 处理过程中如需读取 Nginx 变量Var、请求体ReqBody或响应体RespBody可通过该 RPC 向 APISIX 拉取对应实现为 handle_extra_infoRPC_HTTP_RESP_CALL响应调用由ext-plugin-post-resp使用。before_proxy阶段先向上游发起一次真实请求拿到响应再把响应状态、响应头传给 Runner 做后处理Runner 可返回新的状态码与响应体。Socket 地址的确定helper.get_path()优先读取本地配置中的ext-plugin.path_for_test若配置则以unix:前缀拼接否则动态生成./conf/apisix-master_pid.sock的绝对路径见 helper.lua 第 30-51 行。超时重试与降级_M.communicate()封装了 RPC 调用的统一入口见 init.lua 第 873-907 行每次调用最多重试3 次若失败原因包含conf token not found会先刷新缓存recreate_lrucache会 flush 共享字典与 lrucache后重试当配置了allow_degradation true时Runner 异常会记录告警并放行请求降级为正常转发未配置时直接返回503 Service Unavailable。它是如何实现的如果你对 Plugin Runner 的内部实现例如 Runner 侧如何解析 FlatBuffers 协议、如何注册外部插件、Java / Go 版本的对象模型与线程模型感兴趣请参阅 Plugin Runner 实现文档。仓库内针对 ext-plugin 的协议客户端测试也提供了很好的实现参考例如 t/plugin/ext-plugin/sanity.t进程管理与 socket 通信冒烟测试、t/plugin/ext-plugin/http-req-call.t、t/plugin/ext-plugin/conf_token.t、t/plugin/ext-plugin/extra-info.t、t/plugin/ext-plugin/request-body.t、t/plugin/ext-plugin/response.t。支持的 Plugin Runner官方及社区提供的 Plugin Runner 实现如下Javaapache/apisix-java-plugin-runnerGoapache/apisix-go-plugin-runnerPythonapache/apisix-python-plugin-runnerJavaScriptzenozeng/apisix-javascript-plugin-runner这些 Runner 均实现了与 APISIX 的 RPC 协议你只需按其 README 编写插件并构建出可执行文件再按下一节的步骤接入 APISIX。在 APISIX 中配置 Plugin Runner生产环境由 APISIX 托管 Runner在生产环境把 Runner 的可执行文件路径配置到conf/config.yaml中APISIX 将以子进程方式管理该 Runnerext-plugin: cmd: [blah] # 替换为实际 Runner 可执行文件及参数例如 Go Runner 的二进制路径配置说明cmd是一个字符串数组第一个元素是 Runner 可执行文件的路径后续元素为其启动参数APISIX 启动时会在 privileged agent 进程中拉起该子进程并负责其生命周期重启、守护、退出清理生产环境下不要配置path_for_test此时 APISIX 会自动生成监听地址./conf/apisix-master_pid.sock无需手工指定。注意在 Mac 上APISIXv2.6版本无法管理该 Plugin Runner该限制在后续版本中已解决请以你所使用版本的官方说明为准。在 conf/config.yaml.example 中也给出了默认注释示例# ext-plugin: # cmd: [ls, -l]同时ext-plugin-pre-reqpriority: 12000、ext-plugin-post-reqpriority: -3000、ext-plugin-post-resppriority: -4000三个插件已默认列入启用插件列表见 conf/config.yaml.example 第 552 行与第 662-663 行。开发环境独立运行 Runner开发过程中我们希望单独运行 Plugin Runner这样可以只重启 Runner 而无需重启整个 APISIX。通过指定环境变量APISIX_LISTEN_ADDRESS可以让 Plugin Runner 监听一个固定地址例如APISIX_LISTEN_ADDRESSunix:/tmp/x.sock此时 Plugin Runner 将监听/tmp/x.sock。同时需要配置 APISIX 把 RPC 请求发送到这个固定地址注意path_for_test的值不带unix:前缀ext-plugin: # cmd: [blah] # 不要配置可执行文件 path_for_test: /tmp/x.sock # 不带 unix: 前缀开发模式配置要点必须注释掉cmd否则 APISIX 会再次托管拉起一个 Runner与手工启动的实例冲突path_for_test指定 APISIX 连接 Runner 的固定 socket 路径生产环境不应使用path_for_test此时监听地址由 APISIX 动态生成。在路由上启用外部插件完成 Runner 配置后即可像普通插件一样通过 Admin API 为路由配置外部插件。例如curl http://127.0.0.1:9180/apisix/admin/routes/1 -X PUT -d { uri: /hello, plugins: { ext-plugin-pre-req: { conf: [ {name: my-echo, value: bar} ] } }, upstream: { type: roundrobin, nodes: {127.0.0.1:1980: 1} } }其中conf数组中的name是 Runner 内已注册的外部插件名value是传给该插件的配置字符串具体解析方式由 Runner 侧插件决定。执行顺序即conf数组的顺序。外部插件支持动态启用、重新配置无需重启 APISIX。常见问题FAQPlugin Runner 由 APISIX 管理时无法访问我的环境变量自 APISIXv2.7起APISIX 可以将环境变量传递给 Plugin Runner。但默认情况下 Nginx 会隐藏所有环境变量因此需要先在conf/config.yaml中显式声明要透传的变量nginx_config: envs: - MY_ENV_VAR在 conf/config.yaml.example 中同样可以看到nginx_config段用于声明需要暴露给 Nginx/子进程的环境变量。若未声明Runner 子进程将看不到宿主机上的自定义环境变量。APISIX 使用 SIGKILL 终止 Plugin Runner而不是使用 SIGTERM自v2.7起当运行在 OpenResty 1.19 时APISIX 会改用SIGTERM来停止 Plugin Runner详见 exit_worker 的实现先runner:kill(SIGTERM)再core.os.waitpid(pid, 1)等待最多 1 秒。APISIX 需要等待 Plugin Runner 退出这样才能确保 Runner 持有的资源连接、临时文件等被充分释放。因此其策略是先发送SIGTERM给 Runner 1 秒时间优雅退出、清理资源若 1 秒后 Runner 仍在运行则发送SIGKILL强制终止。小结外部插件机制让 APISIX 摆脱了“只能用 Lua 写插件”的限制通过 Sidecar 形态的 Plugin Runner 与基于 Unix Socket FlatBuffers 的 RPC 协议把 Java、Go、Python、JavaScript 生态无缝接入 API 网关接入路径选择官方 Runner → 编写外部插件 → 配置ext-plugin.cmd生产或APISIX_LISTEN_ADDRESSpath_for_test开发→ 在路由上启用ext-plugin-*运行机制Runner 由 APISIX 以子进程托管并自动守护重启通信复用连接池配置令牌conf token缓存避免重复全量下发配置可靠性内置 3 次重试、令牌缓存刷新、allow_degradation降级放行以及先 SIGTERM 后 SIGKILL 的退出清理策略。无论是网关能力扩展还是团队技术栈复用外部插件机制都是 APISIX 生态中值得优先了解的高价值能力。赞分享API网关后端云原生微服务【免费下载链接】apisixThe Cloud-Native API Gateway and AI Gateway项目地址https://gitcode.com/gh_mirrors/api/apisix点击查看免费下载相关推荐APISIX External Plugin外部插件与 Plugin Runner 多语言插件开发指南APISIX External Plugin外部插件与 Plugin Runner 多语言插件开发指南 APISIX 的原生插件基于 Lua 编写并运行于网API网关后端云原生微服务Apache APISIX 外部插件External Plugin机制完全指南Plugin Runner 架构、配置与源码实现Apache APISIX 外部插件External Plugin机制完全指南Plugin Runner 架构、配置与源码实现 APISIX 官方文档后端微服务云原生APISIX 外部插件External Plugin与 Plugin Runner 完全指南跨语言插件开发、Sidecar 运行机制与生产配置APISIX 外部插件External Plugin与 Plugin Runner 完全指南跨语言插件开发、Sidecar 运行机制与生产配置 APISI后端微服务云原生创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Cockpit SELinux 策略开发指南:修改、重建与快速迭代 cockpit 的 SELinux 策略模块

Cockpit SELinux 策略开发指南:修改、重建与快速迭代 cockpit 的 SELinux 策略模块

Cockpit SELinux 策略开发指南:修改、重建与快速迭代 cockpit 的 SELinux 策略模块 【免费下载链接】cockpit Cockpit is a web-based graphical interface for servers. 项目地址: https://gitcode.com/gh_mirrors/co/cockpit Cockpit 作为面向服务器的 Web…

2026/9/21 14:42:01 阅读更多 →
AI前端面试实战:SSE与WebSocket流式交互及TS类型攻坚

AI前端面试实战:SSE与WebSocket流式交互及TS类型攻坚

1. 这不是“AI前端面试指南”,而是9月真实考场的生存手记“最后提醒一次,9月的AI前端面试不用太老实”——这句话刚在技术群刷出来时,我正蹲在会议室门口改第三版WebSocket心跳包重连逻辑。不是故作玄虚,是真有人在面试现场被问到…

2026/9/21 14:41:00 阅读更多 →
Avalonia ViewModels 实战指南:用 Zafiro 与 ReactiveUI 构建响应式 MVVM 架构

Avalonia ViewModels 实战指南:用 Zafiro 与 ReactiveUI 构建响应式 MVVM 架构

AI 技能AI 插件 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,400 agentic skills. Includes CLI, local MCP, catalog, …

2026/9/21 14:41:00 阅读更多 →

最新新闻

3个方案对比:卡点视频生成技术图解原理

3个方案对比:卡点视频生成技术图解原理

3个方案对比:卡点视频生成技术图解原理 别再去翻那几百页的官方文档了,真的,没人有那个耐心。想搞懂 卡点视频 怎么在代码里实现,盯着 FFmpeg 或者 MoviePy 的英文 API 看,眼睛都花了还是抓不住重点。这时候,你需要的是…

2026/9/21 19:12:51 阅读更多 →
Handsontable 服务端数据实战:用 Django REST Framework 实现分页、排序、过滤与批量 CRUD 数据网格

Handsontable 服务端数据实战:用 Django REST Framework 实现分页、排序、过滤与批量 CRUD 数据网格

前端UI组件 【免费下载链接】handsontable JavaScript Data Grid / Data Table with a Spreadsheet Look & Feel. Works with React, Angular, and Vue. Supported by the Handsontable team ⚡ 项目地址: https://gitcode.com/gh_mirrors/ha/handsontable 点击…

2026/9/21 19:12:51 阅读更多 →
罗技鼠标宏源码解析:避开官方文档的5个隐形坑

罗技鼠标宏源码解析:避开官方文档的5个隐形坑

罗技鼠标宏源码解析:避开官方文档的5个隐形坑 Logitech G Hub 的官方文档像天书,翻半天只看到“支持按键映射”,却没人告诉你底层怎么跑。想搞懂罗技鼠标宏的 源码解析 ,别死磕 PDF,直接看执行逻辑。…

2026/9/21 19:12:51 阅读更多 →
FreshRSS WebSub 订阅数据目录全解析:`data/PubSubHubbub/feeds` 目录结构与推送机制

FreshRSS WebSub 订阅数据目录全解析:`data/PubSubHubbub/feeds` 目录结构与推送机制

FreshRSS WebSub 订阅数据目录全解析:data/PubSubHubbub/feeds 目录结构与推送机制 【免费下载链接】FreshRSS A free, self-hostable news aggregator… 项目地址: https://gitcode.com/gh_mirrors/fr/FreshRSS FreshRSS 原生支持 WebSub(原名 P…

2026/9/21 19:12:51 阅读更多 →
Vitess v23.0.6 发布详解:VReplication、VTGate 表达式引擎与复制链路的关键修复

Vitess v23.0.6 发布详解:VReplication、VTGate 表达式引擎与复制链路的关键修复

Vitess v23.0.6 发布详解:VReplication、VTGate 表达式引擎与复制链路的关键修复 【免费下载链接】vitess Vitess is a database clustering system for horizontal scaling of MySQL. 项目地址: https://gitcode.com/gh_mirrors/vi/vitess 本篇文章基于 Vit…

2026/9/21 19:12:51 阅读更多 →
gbrain 工作区模板仓库(template-repo)完全指南:从 Use this template 到持久化个人 Agent

gbrain 工作区模板仓库(template-repo)完全指南:从 Use this template 到持久化个人 Agent

gbrain 工作区模板仓库(template-repo)完全指南:从 Use this template 到持久化个人 Agent 【免费下载链接】gbrain Garrys Opinionated OpenClaw/Hermes Agent Brain 项目地址: https://gitcode.com/gh_mirrors/gb/gbrain 本指南以 g…

2026/9/21 19:11:51 阅读更多 →

日新闻

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and …

2026/9/21 0:00:01 阅读更多 →
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,…

2026/9/21 0:00:01 阅读更多 →
Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

桌面应用AI 应用插件系统 【免费下载链接】Wox A cross-platform launcher that simply works 项目地址: https://gitcode.com/gh_mirrors/wo/Wox 点击查看 免费下载 全功能插件(Full-featured Plugin)是 Wox 三类插件实现方式中能力最完整的…

2026/9/21 0:00:01 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/21 4:51:05 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →