apisix中插件的优先级顺序

执行顺序介绍

apisix中插件的执行顺序由两个因素决定,首先是执行阶段phase),如下所示,主要包括:rewrite → access → before_proxy → header_filter → body_filter → log几个阶段。

其次,影响执行顺序的还有一个因素priority ,在apisix的配置文件config.yaml中的plugins节点有记载,大致如下,不同版本可能不太一样,仅做参考。

plugins:                           # plugin list (sorted by priority)
  - real-ip                        # priority: 23000
  - ai                             # priority: 22900
  - client-control                 # priority: 22000
  - proxy-control                  # priority: 21990
  - request-id                     # priority: 12015
  - zipkin                         # priority: 12011
  #- skywalking                    # priority: 12010
  #- opentelemetry                 # priority: 12009
  - ext-plugin-pre-req             # priority: 12000
  - fault-injection                # priority: 11000
  - mocking                        # priority: 10900
  - serverless-pre-function        # priority: 10000
  #- batch-requests                # priority: 4010
  - cors                           # priority: 4000
  - ip-restriction                 # priority: 3000
  - ua-restriction                 # priority: 2999
  - referer-restriction            # priority: 2990
  - csrf                           # priority: 2980
  - uri-blocker                    # priority: 2900
  - request-validation             # priority: 2800
  - chaitin-waf                    # priority: 2700
  - multi-auth                     # priority: 2600
  - openid-connect                 # priority: 2599
  - cas-auth                       # priority: 2597
  - authz-casbin                   # priority: 2560
  - authz-casdoor                  # priority: 2559
  - wolf-rbac                      # priority: 2555
  - ldap-auth                      # priority: 2540
  - hmac-auth                      # priority: 2530
  - basic-auth                     # priority: 2520
  - jwt-auth                       # priority: 2510
  - jwe-decrypt                    # priority: 2509
  - key-auth                       # priority: 2500
  - consumer-restriction           # priority: 2400
  - attach-consumer-label          # priority: 2399
  - forward-auth                   # priority: 2002
  - opa                            # priority: 2001
  - authz-keycloak                 # priority: 2000
  #- error-log-logger              # priority: 1091
  - proxy-cache                    # priority: 1085
  - body-transformer               # priority: 1080
  - ai-prompt-template             # priority: 1071
  - ai-prompt-decorator            # priority: 1070
  - proxy-mirror                   # priority: 1010
  - proxy-rewrite                  # priority: 1008
  - workflow                       # priority: 1006
  - api-breaker                    # priority: 1005
  - limit-conn                     # priority: 1003
  - limit-count                    # priority: 1002
  - limit-req                      # priority: 1001
  #- node-status                   # priority: 1000
  - ai-proxy                       # priority: 999
  #- brotli                        # priority: 996
  - gzip                           # priority: 995
  - server-info                    # priority: 990
  - traffic-split                  # priority: 966
  - redirect                       # priority: 900
  - response-rewrite               # priority: 899
  - degraphql                      # priority: 509
  - kafka-proxy                    # priority: 508
  #- dubbo-proxy                   # priority: 507
  - grpc-transcode                 # priority: 506
  - grpc-web                       # priority: 505
  - http-dubbo                     # priority: 504
  - public-api                     # priority: 501
  - prometheus                     # priority: 500
  - datadog                        # priority: 495
  - loki-logger                    # priority: 414
  - elasticsearch-logger           # priority: 413
  - echo                           # priority: 412
  - loggly                         # priority: 411
  - http-logger                    # priority: 410
  - splunk-hec-logging             # priority: 409
  - skywalking-logger              # priority: 408
  - google-cloud-logging           # priority: 407
  - sls-logger                     # priority: 406
  - tcp-logger                     # priority: 405
  - kafka-logger                   # priority: 403
  - rocketmq-logger                # priority: 402
  - syslog                         # priority: 401
  - udp-logger                     # priority: 400
  - file-logger                    # priority: 399
  - clickhouse-logger              # priority: 398
  - tencent-cloud-cls              # priority: 397
  - inspect                        # priority: 200
  #- log-rotate                    # priority: 100
  # <- recommend to use priority (0, 100) for your custom plugins
  - example-plugin                 # priority: 0
  #- gm                            # priority: -43
  #- ocsp-stapling                 # priority: -44
  - file-upload-filter             # priority: -99
  - aws-lambda                     # priority: -1899
  - azure-functions                # priority: -1900
  - openwhisk                      # priority: -1901
  - openfunction                   # priority: -1902
  - serverless-post-function       # priority: -2000
  - ext-plugin-post-req            # priority: -3000
  - ext-plugin-post-resp           # priority: -4000

总结: 两个(phasepriority)结合起来的影响,先根据执行阶段(phase)排序,相同的执行阶段内,再根据priority 的大小排序,priority值越大,越先执行。如果没有中途停止(比如高危请求直接中断返回),插件和阶段都会按顺序执行,也就是说只有满足所有插件规则的请求,最终才会到服务器。

案例说明

拿serverless-post-function与serverless-pre-function两个插件来举例

场景一:不同插件在相同phase

由配置文件可知,serverless-post-functionpriority值为 -2000;serverless-pre-functionpriority值为 10000。当两个插件在相同阶段时,两个插件的执行顺序仅根据priority值来区分,值越大优先级越高,所以此处先执行的是serverless-pre-function插件,后执行的是serverless-post-function插件

场景二:不同插件在不同phase

将serverless-pre-function插件放在access阶段,将serverless-post-function放在rewrite阶段

由阶段执行顺序(rewrite → access → before_proxy → header_filter → body_filter → log)可知,rewrite阶段在access阶段前,故优先执行serverless-post-function插件,后执行serverless-pre-function插件

配置 serverless-post-function 在 rewrite 阶段

{
  "uri": "/example/*",
  "plugins": {
    "serverless-post-function": {
      "phase": "rewrite",
      "functions": [
        "return function(conf, ctx) ngx.log(ngx.INFO, 'This is serverless-post-function in rewrite phase') end"
      ]
    }
  },
  "upstream": {
    "type": "roundrobin",
    "nodes": {
      "127.0.0.1:1980": 1
    }
  }
}

配置 serverless-pre-function 在 access 阶段

{
  "uri": "/example/*",
  "plugins": {
    "serverless-pre-function": {
      "phase": "access",
      "functions": [
        "return function(conf, ctx) ngx.log(ngx.INFO, 'This is serverless-pre-function in access phase') end"
      ]
    }
  },
  "upstream": {
    "type": "roundrobin",
    "nodes": {
      "127.0.0.1:1980": 1
    }
  }
}

各个阶段上下文参数

插件在不同阶段(如 rewrite、access、header_filter、body_filter 等)执行时,上下文参数 conf 和 ctx 的基本结构是一致的,但它们的 可用数据和行为 会因阶段的不同而有所差异。以下是各阶段的上下文参数详解:

1. 上下文参数概览

conf:插件的配置参数,通常由用户在路由或全局插件配置中定义。
ctx:请求上下文对象,包含请求和响应的元数据(如 URI、请求头、响应状态码等)。

2. 各阶段的上下文参数差异

阶段 1:rewrite
执行时机: 请求到达 APISIX 后,修改请求 URI 或参数。
conf: 插件配置(如 uri_rewrite 规则)。
ctx:

  • 包含请求信息(如 ctx.var.uri、ctx.var.args)。
  • 不支持响应信息(如 ctx.var.status)。
    示例:
function _M.rewrite(conf, ctx)
    ngx.log(ngx.INFO, "URI: ", ctx.var.uri)
    ctx.var.uri = "/new-path"  -- 修改请求 URI
end

阶段 2:access
执行时机: 请求转发到上游服务之前,用于鉴权、限流等。
conf: 插件配置(如 limit-count 的限流规则)。
ctx:

  • 包含完整的请求信息(如 ctx.var.request_uri、ctx.var.http_*)。
  • 不支持响应信息。
    示例:
function _M.access(conf, ctx)
    if ctx.var.http_token ~= "secret" then
        return 403, { message = "Forbidden" }
    end
end

阶段 3:before_proxy
执行时机: 请求即将转发到上游服务之前,用于修改请求头或参数。
conf: 插件配置(如 proxy-rewrite 的请求头修改规则)。
ctx:

  • 包含请求信息(如 ctx.var.http_*)。
  • 不支持响应信息。
    示例:
function _M.before_proxy(conf, ctx)
    ngx.req.set_header("X-Custom-Header", "value")
end

阶段 4:header_filter
执行时机: 接收到上游响应头后,用于修改响应头。
conf: 插件配置(如 response-rewrite 的响应头规则)。
ctx:

  • 包含响应头信息(如 ctx.var.status、ctx.var.header_*)。
  • 不支持请求信息(如 ctx.var.uri)。
    示例:
function _M.header_filter(conf, ctx)
    ngx.header["X-APISIX-Version"] = "1.0"
end

阶段 5:body_filter
执行时机: 接收到上游响应体后,用于修改响应体。

conf: 插件配置(如 response-rewrite 的响应体规则)。

ctx:

  • 包含响应信息(如 ctx.var.status、ctx.var.body)。
  • 不支持请求信息。
    示例:
function _M.body_filter(conf, ctx)
    local body = ngx.arg[1]
    if body then
        ngx.arg[1] = body:gsub("foo", "bar")  -- 修改响应体
    end
end

阶段 6:log
执行时机: 请求处理完成后,用于记录日志。
conf: 插件配置(如 kafka-logger 的日志格式)。
ctx:

  • 包含完整的请求和响应信息(如 ctx.var.request_uri、ctx.var.status)。

示例:

function _M.log(conf, ctx)
    ngx.log(ngx.INFO, "Request completed: ", ctx.var.request_uri, " Status: ", ctx.var.status)
end

上下文参数对比表

阶段conf 可用性ctx 可用请求信息ctx 可用响应信息
rewrite✔️✔️
access✔️✔️
before_proxy✔️✔️
header_filter✔️✔️
body_filter✔️✔️
log✔️✔️✔️

4. 注意事项
阶段限制: 某些变量(如 ctx.var.body)仅在特定阶段可用,需根据阶段选择合适操作。
性能影响: 在 body_filter 阶段修改响应体可能增加延迟,建议优化逻辑。
调试建议: 使用 ngx.log 记录调试信息,结合 APISIX 日志定位问题。

总结
conf: 在所有阶段均可用,表示插件配置。
ctx: 在不同阶段包含不同的请求和响应信息,需根据阶段合理使用。
阶段选择: 根据需求选择合适的阶段(如 rewrite 修改请求,header_filter 修改响应头)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值