title: Plugin keywords:
APISIX 插件可以扩展 APISIX 的功能,以满足组织或用户特定的流量管理、可观测性、安全、请求/响应转换、无服务器计算等需求。
APISIX 提供了许多现有的插件,可以定制和编排以满足你的需求。这些插件可以全局启用,以在每个传入请求上触发,也可以局部绑定到其他对象,例如在 Route、Service、Consumer 或 Plugin Config 上。你可以参考 Admin API 了解如何使用该资源。
如果现有的 APISIX 插件不满足需求,你还可以使用 Lua 或其他语言(如 Java、Python、Go 和 Wasm)编写自定义插件。
默认情况下,大多数 APISIX 插件都已安装:
local _M = { ... plugins = { "real-ip", "ai", "client-control", "proxy-control", "request-id", "zipkin", "ext-plugin-pre-req", "fault-injection", "mocking", "serverless-pre-function", ... }, ... }
如果您想调整插件安装,请将自定义的 plugins
配置添加到 config.yaml
中。例如:
plugins: - real-ip # 安装 - ai - real-ip - ai - client-control - proxy-control - request-id - zipkin - ext-plugin-pre-req - fault-injection # - mocking # 不安装 - serverless-pre-function ... # 其它插件
完整配置参考请参见 config.yaml.example
。
重新加载 APISIX 以使配置更改生效。
安装的插件首先会被初始化。然后会检查插件的配置,以确保插件配置遵循定义的JSON Schema。
当一个请求通过 APISIX 时,插件的相应方法会在以下一个或多个阶段中执行: rewrite
, access
, before_proxy
, header_filter
, body_filter
, and log
。这些阶段在很大程度上受到OpenResty 指令的影响。
通常情况下,插件按照以下顺序执行:
全局规则 插件
绑定到其他对象的插件
在每个阶段内,你可以在插件的 _meta.priority
字段中可选地定义一个新的优先级数,该优先级数优先于默认插件优先级在执行期间。具有更高优先级数的插件首先执行。
例如,如果你想在请求到达路由时,让 limit-count
(优先级 1002)先于 ip-restriction
(优先级 3000)运行,可以通过将更高的优先级数传递给 limit-count
的 _meta.priority
字段来实现:
{ ..., "plugins": { "limit-count": { ..., "_meta": { "priority": 3010 } } } }
若要将此插件实例的优先级重置为默认值,只需从插件配置中删除_meta.priority
字段即可。
当同一个插件在全局规则中和局部规则(例如路由)中同时配置时,两个插件将顺序执行。
然而,如果相同的插件在多个对象上本地配置,例如在Route
, Service
, Consumer
或Plugin Config
上,每个非全局插件只会执行一次,因为在执行期间,针对特定的优先顺序,这些对象中配置的插件会被合并:
Consumer
> Consumer Group
> Route
> Plugin Config
> Service
因此,如果相同的插件在不同的对象中具有不同的配置,则合并期间具有最高优先顺序的插件配置将被使用。
通过 _meta
配置项可以将一些通用的配置应用于插件,你可以参考下文使用这些通用配置。通用配置如下:
名称 | 类型 | 描述 |
---|---|---|
disable | boolean | 当设置为 true 时,则禁用该插件。可选值为 true 和 false 。 |
error_response | string/object | 自定义错误响应。 |
priority | integer | 自定义插件优先级。 |
filter | array | 根据请求的参数,在运行时控制插件是否执行。此配置由一个或多个 {var, operator, val} 元素组成列表,类似:{{var, operator, val}, {var, operator, val}, ...}} 。例如 {"arg_version", "==", "v2"} ,表示当前请求参数 version 是 v2 。这里的 var 与 NGINX 内部自身变量命名是保持一致。操作符的使用方法,请参考 lua-resty-expr。 |
通过 disable
参数,你可以将某个插件调整为“禁用状态”,即请求不会经过该插件。
{ "proxy-rewrite": { "_meta": { "disable": true } } }
通过 error_response
配置,可以将任意插件的错误响应配置成一个固定的值,避免因为插件内置的错误响应信息而带来不必要的麻烦。
如下配置表示将 jwt-auth
插件的错误响应自定义为 Missing credential in request
。
{ "jwt-auth": { "_meta": { "error_response": { "message": "Missing credential in request" } } } }
所有插件都有默认优先级,但是你仍然可以通过 priority
配置项来自定义插件优先级,从而改变插件执行顺序。
{ "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
的默认优先级是 10000
,serverless-post-function
的默认优先级是 -2000
。默认情况下会先执行 serverless-pre-function
插件,再执行 serverless-post-function
插件。
上面的配置则将 serverless-pre-function
插件的优先级设置为 -2000
,serverless-post-function
插件的优先级设置为 10000
,因此 serverless-post-function
插件会优先执行。
:::note 注意
serverless-post-function
和 serverless-post-function
插件执行顺序不会受到影响,会使用默认优先级。rewrite
阶段。路由上配置的插件的 rewrite
阶段将会优先运行,然后才会运行 Consumer 上除 auth
类插件之外的其他插件的 rewrite
阶段。:::
默认情况下,在路由中指定的插件都会被执行。但是你可以通过 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
插件不会执行,请求将被转发到上游的 /get
。
curl -v /dev/null http://127.0.0.1:9080/get -H"host: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": "Root=1-62eb6eec-46c97e8a5d95141e621e07fe",
"X-Forwarded-Host": "httpbin.org"
},
"origin": "127.0.0.1, 117.152.66.200",
"url": "http://httpbin.org/get"
}
当请求中携带参数 version=v2
时,proxy-rewrite
插件执行,请求将被转发到上游的 /anything
:
curl -v /dev/null http://127.0.0.1:9080/get?version=v2 -H"host: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": "Root=1-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?version=v2"
}
APISIX 的插件是热加载的,不管你是新增、删除还是修改插件,都不需要重启服务。
只需要通过 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 注意
如果你已经在路由规则里配置了某个插件(比如在 Route 的 plugins
字段里面添加了它),然后在配置文件中禁用了该插件,在执行路由规则时则会跳过该插件。
:::
关于 Stand Alone 模式下的热加载的信息,请参考 stand alone 模式。