Apache APISIX 插件(Plugin)完全指南:安装、执行生命周期、优先级、合并规则与热加载

发布时间:2026/9/15 14:41:17
Apache APISIX 插件(Plugin)完全指南:安装、执行生命周期、优先级、合并规则与热加载 Apache APISIX 插件Plugin完全指南安装、执行生命周期、优先级、合并规则与热加载【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisix导读本文以 Apache APISIX 官方术语文档docs/en/latest/terminology/plugin.md为骨架系统讲解 APISIX 中Plugin插件这一核心对象它如何扩展网关能力、如何在config.yaml中声明加载、如何按生命周期阶段执行、如何通过_meta配置项实现禁用、自定义错误响应、自定义优先级与运行时条件过滤以及插件合并的优先级顺序与热加载机制。读完本文你将掌握在 Route、Service、Consumer、Consumer Group、Plugin Config 上正确挂载与调优插件的完整实战方法并能结合源码理解插件执行的底层原理。什么是 APISIX PluginPlugin 是 APISIX 用于扩展网关能力的基本单元覆盖流量管理、可观测性、安全防护、请求/响应转换、Serverless 计算等场景。它解决组织或用户有特定需求但内置能力不够用的问题例如限流、鉴权、日志上报、URL 重写等都可以通过插件以声明式配置的方式接入而无需修改网关核心代码。一个 Plugin 配置可以被直接绑定到以下对象之一详见文档 docs/en/latest/terminology/plugin.mdRoute路由Service服务Consumer消费者Plugin Config插件配置模板关于这些资源如何通过 Admin API 管理可参考 Admin API plugins 章节。如果现有插件无法满足需求你还可以自行编写插件。APISIX 的插件主要由 Lua 编写位于 apisix/plugins 目录同时支持通过外部插件 Runner 使用 Java、Python、Go 等语言以及通过 apisix/wasm.lua 支持 Wasm 插件。插件的安装与加载config.yaml 中的 plugins 声明APISIX 自带一个默认配置文件config-default.yaml和一个用户自定义配置文件config.yaml两者都位于conf目录仓库中默认配置为 conf/config.yaml完整示例见 conf/config.yaml.example。如果两个文件中存在相同 key例如plugins则config.yaml中的配置值会覆盖config-default.yaml中的值。plugins配置块用于声明要加载到当前 APISIX 实例的插件列表plugins: - real-ip # loaded - ai - client-control - proxy-control - request-id - zipkin # - skywalking # not loaded ...只出现在config.yaml的plugins列表中、并被启用的插件才会在运行时被加载被注释掉如上面的skywalking的插件则不会被加载。从 apisix/cli/config.lua 可以看到本仓库默认启用的 HTTP 插件列表real-ip、ai、client-control、proxy-control、request-id、zipkin、cors、ip-restriction、limit-conn、limit-count、limit-req、jwt-auth、key-auth等以及默认的流式插件列表stream_pluginsip-restriction、limit-conn、mqtt-proxy、syslog。提示在 etcd 配置中心模式下你也可以通过 Admin API 的PUT /apisix/admin/plugins/reload动态变更已加载插件集合详见下文热加载小节。加载与校验的底层过程在源码层面插件的加载与校验由 apisix/plugin.lua 完成。核心逻辑包括load_plugin通过require(apisix.plugins. .. name)加载插件模块并强制校验插件必须提供priority与version字段否则视为非法插件apisix/plugin.lua。init_worker在 worker 启动时调用_M.load()完成插件加载并通过/plugins与/plugin_metadata两个 etcd key 同步插件配置apisix/plugin.lua。插件配置的 schema 校验会先校验插件自身 schema再校验注入的_meta字段见下文插件通用配置。插件的执行生命周期Phases一个已安装的插件会首先被初始化随后插件的配置会依据定义的 JSON Schema 进行校验确保配置格式正确。当请求流经 APISIX 时插件对应的方法会在以下一个或多个阶段phase中被执行rewrite重写阶段适合做 URI 重写、参数改写等access访问控制阶段适合做鉴权、限流等before_proxy转发到上游之前header_filter上游响应头过滤body_filter上游响应体过滤log日志阶段这些阶段很大程度上受 OpenResty 指令 依次驱动http_access_phase中先执行全局规则再执行路由插件见 apisix/init.lua其中rewrite与access阶段通过plugin.run_plugin调用apisix/plugin.lua。执行顺序一般情况下插件按如下顺序执行全局规则 中的插件rewrite阶段的插件access阶段的插件绑定在其他对象上的插件rewrite阶段的插件access阶段的插件在每个阶段内部可以通过插件配置的_meta.priority字段自定义优先级该值优先于插件的默认优先级参与排序优先级数值越大的插件越先执行。插件优先级排序逻辑见 apisix/plugin.lua当检测到任意插件配置了_meta.priority时会启用custom_sort把未显式设置优先级的插件回退为默认plugin_obj.priority再按优先级降序重排。从源码结构看apisix/plugin.lua 中的sort_plugin与custom_sort_plugin分别对应默认排序与自定义排序二者都采用数值大者优先的规则。插件的合并优先级Merging Precedence当同一个插件同时配置在全局规则Global Rule和某个对象如 Route上时两个插件实例会依次都执行全局规则先执行。但是如果同一个插件配置在多个局部对象上例如同时配置在 Route、Service、Consumer、Consumer Group 或 Plugin Config 上由于每个非全局插件只会执行一次因此只会使用一份配置。执行时这些对象上的插件会按照以下优先级顺序进行合并Consumer Consumer Group Route Plugin Config Service即如果同一个插件在不同对象上有不同配置合并时采用优先级最高对象的插件配置。该合并行为在源码中有清晰对应Route 与 Service 的插件合并由merge_service_route实现Route 上的插件会覆盖 Service 上的同名插件apisix/plugin.luaConsumer 与 Consumer Group 的插件合并由merge_consumer_route实现先合并 Consumer Group 插件再合并 Consumer 插件后合并者覆盖前者的同名插件即 Consumer 的配置优先于 Consumer Groupapisix/plugin.lua请求处理时http_access_phase会先通过plugin_config.get拉取 Plugin Config 并merge到 Routeapisix/init.lua再合并 Service、Consumer 插件apisix/init.lua。插件通用配置_metaAPISIX 为所有插件注入了一套通用配置项_meta。从 apisix/schema_def.lua 可以看到plugin_injected_schema定义了_meta对象的四个字段并在 apisix/plugin.lua 中被注入到每个插件的 schema 中名称类型描述disableboolean设置为true时插件被禁用。error_responsestring/object自定义错误响应。priorityinteger自定义插件优先级。filterarray根据请求参数在运行时决定插件是否执行。形如{{var, operator, val}, {var, operator, val}, ...}}。例如{arg_version, , v2}表示当前请求参数version为v2。变量与 NGINX 内部变量一致支持的运算符详见 lua-resty-expr 的 operator list。下面逐一介绍四个配置项的用法。禁用插件disable通过disable配置可以添加一个处于禁用状态的插件请求将不会经过该插件{ proxy-rewrite: { _meta: { disable: true } } }在源码中check_disable负责读取_meta.disableapisix/plugin.luafilter函数在收集插件时会跳过被禁用的插件apisix/plugin.lua。流式插件同样适用该逻辑apisix/plugin.lua。自定义错误响应error_response通过error_response配置可以把任意插件的错误响应固定为一个自定义值避免暴露插件内置错误信息带来的困扰。下面的配置将jwt-auth插件的错误响应自定义为Missing credential in request{ jwt-auth: { _meta: { error_response: { message: Missing credential in request } } } }从源码看当插件以code 400的 HTTP 状态码退出时apisix/plugin.lua 会检查conf._meta.error_response只要配置了该字段无论插件原本输出什么错误信息都会统一返回配置的内容从而避免调用方猜测真实错误原因。error_response的类型既可以是字符串也可以是对象oneOf定义见 apisix/schema_def.lua。自定义插件优先级priority所有插件都有默认优先级通过priority配置项可以自定义插件优先级、改变插件执行顺序。例如将serverless-pre-function的优先级调低、把serverless-post-function的优先级调高{ serverless-post-function: { _meta: { priority: 10000 }, phase: rewrite, functions : [return function(conf, ctx) ngx.say(\serverless-post-function\); end] }, serverless-pre-function: { _meta: { priority: -2000 }, phase: rewrite, functions: [return function(conf, ctx) ngx.say(\serverless-pre-function\); end] } }serverless-pre-function的默认优先级是 10000serverless-post-function的默认优先级是 -2000对应源码 apisix/plugins/serverless-pre-function.lua 与 apisix/plugins/serverless-post-function.lua二者通过 apisix/plugins/serverless/init.lua 的工厂函数以priority参数创建。默认情况下serverless-pre-function先执行、serverless-post-function后执行。而上述配置把serverless-pre-function的优先级设为 -2000、serverless-post-function设为 10000结果变成serverless-post-function先执行、serverless-pre-function后执行。:::note 注意事项自定义插件优先级只影响当前对象route、service 等上绑定的插件实例不影响该插件的其他实例。例如上述配置属于 Route A则 Route B 上serverless-post-function与serverless-pre-function的执行顺序不受影响仍使用默认优先级。自定义插件优先级不适用于配置在 consumer 上部分插件的 rewrite 阶段route 上插件的 rewrite 阶段会先执行然后才执行 consumer 上插件不含 auth 插件的 rewrite 阶段。对应逻辑可见 apisix/plugin.lua 中rewrite_in_consumer阶段的处理以及 apisix/init.lua 中 consumer 插件合并后对 rewrite 阶段的二次执行。:::动态控制插件是否执行filter默认情况下路由中指定的所有插件都会执行。通过filter配置项可以为插件添加一个过滤条件根据过滤条件的求值结果动态决定插件是否执行。下面的配置表示仅当请求查询参数中的version值为v2时proxy-rewrite插件才会执行{ proxy-rewrite: { _meta: { filter: [ [arg_version, , v2] ] }, uri: /anything } }完整路由示例创建一个完整路由{ uri: /get, plugins: { proxy-rewrite: { _meta: { filter: [ [arg_version, , v2] ] }, uri: /anything } }, upstream: { type: roundrobin, nodes: { httpbin.org:80: 1 } } }当请求不带任何参数时proxy-rewrite插件不会执行请求被代理到上游的/getcurl -v /dev/null http://127.0.0.1:9080/get -Hhost:httpbin.org HTTP/1.1 200 OK ...... Server: APISIX/2.15.0 { args: {}, headers: { Accept: */*, Host: httpbin.org, User-Agent: curl/7.79.1, X-Amzn-Trace-Id: Root1-62eb6eec-46c97e8a5d95141e621e07fe, X-Forwarded-Host: httpbin.org }, origin: 127.0.0.1, 117.152.66.200, url: http://httpbin.org/get }当请求携带参数versionv2时proxy-rewrite插件被执行请求被代理到上游的/anythingcurl -v /dev/null http://127.0.0.1:9080/get?versionv2 -Hhost:httpbin.org HTTP/1.1 200 OK ...... Server: APISIX/2.15.0 { args: { version: v2 }, data: , files: {}, form: {}, headers: { Accept: */*, Host: httpbin.org, User-Agent: curl/7.79.1, X-Amzn-Trace-Id: Root1-62eb6f02-24a613b57b6587a076ef18b4, X-Forwarded-Host: httpbin.org }, json: null, method: GET, origin: 127.0.0.1, 117.152.66.200, url: http://httpbin.org/anything?versionv2 }filter 的运行时求值原理filter表达式使用resty.expr.v1即 lua-resty-expr进行解析与求值插件配置校验阶段如果存在_meta.filter会调用expr.new预编译表达式以验证其合法性apisix/plugin.lua运行时meta_filter通过expr_lrucache缓存编译结果并用ex:eval(ctx.var)对当前请求变量求值返回true才执行插件求值结果还会按conf_type conf_id conf_version plugin_name缓存到ctx避免同一请求内重复求值apisix/plugin.lua在每个阶段的插件调用处都会先经过meta_filter判断再调用插件方法apisix/plugin.lua。因此filter可以引用任意 NGINX 内部变量如arg_*、http_*、remote_addr等并组合多个条件实现按请求特征开关插件的精细化控制。热加载Hot ReloadAPISIX 插件是热加载的无论是新增、删除、修改插件甚至更新插件代码都无需重启服务。要触发热加载可以通过 Admin API 发送 HTTP 请求:::note 可以从config.yaml中读取admin_key并保存到环境变量admin_key$(yq .deployment.admin.admin_key[0].key conf/config.yaml | sed s///g):::curl http://127.0.0.1:9180/apisix/admin/plugins/reload -H X-API-KEY: $admin_key -X PUT:::note 如果某个配置的插件被禁用disable它的执行会被跳过。:::从源码看热加载的完整链路是Admin API 收到PUT /apisix/admin/plugins/reload请求post_reload_plugins通过events:post广播reload_eventapisix/admin/init.lua事件处理器reload_plugins收到事件后调用plugin.load()完成插件热加载apisix/admin/init.lua非 PUT 方法如 GET、POST访问该路径会被unsupported_methods_reload_plugin拒绝并提示必须使用 PUTapisix/admin/init.lua。standalone 模式下的热加载对于 standalone独立部署模式的热加载请参考 standalone 部署模式 中关于插件的小节。总结APISIX 的 Plugin 体系围绕声明式配置 阶段化执行 可定制元信息构建加载通过conf/config.yaml的plugins列表声明启用配合 Admin API 热加载动态调整执行插件方法分布在rewrite、access、before_proxy、header_filter、body_filter、log等阶段同一阶段内按优先级从高到低执行合并局部对象按Consumer Consumer Group Route Plugin Config Service的优先级合并全局规则插件独立先行执行控制_meta提供的disable、error_response、priority、filter四个通用配置项让插件实例级的行为禁用、错误响应、排序、条件执行全部可动态调整无需重启网关。在此基础上若内置插件无法满足需求可以参照 apisix/plugins 目录下的现有实现如 apisix/plugins/limit-count.lua、apisix/plugins/serverless/init.lua编写自定义 Lua 插件或通过外部插件 Runner 以 Java、Python、Go 与 Wasm 语言扩展能力。【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisix创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考