🤔 Introducing APISIX AI Gateway – Built for LLMs and AI workloads. Learn More

fault-injection

描述

fault-injection 插件通过模拟受控故障或延迟来测试应用程序的弹性。该插件在其他已配置插件之前执行,确保故障被一致性地应用。这使其非常适合混沌工程等场景,用于分析系统在故障条件下的行为。

该插件支持两种主要操作:

  • abort:立即以指定的 HTTP 状态码(例如 503 Service Unavailable)终止请求,跳过所有后续插件。
  • delay:在进一步处理请求之前引入指定的延迟。

INFO

abortdelay 至少需要配置其中一个。

属性

名称类型必选项有效值描述
abortobject终止请求并向客户端返回特定 HTTP 状态码的配置。abortdelay 至少需要配置其中一个。
abort.http_statusinteger[200, …]返回给客户端的 HTTP 状态码。配置 abort 时必填。
abort.bodystring返回给客户端的响应体。支持使用 NGINX 变量,例如 client addr: $remote_addr\n
abort.headersobject返回给客户端的响应头。标头值可包含 NGINX 变量,例如 $remote_addr
abort.percentageinteger[0, 100]被终止的请求占比。若同时配置了 vars,则两个条件都必须满足。
abort.varsarray[]终止请求前需匹配的规则。支持 lua-resty-expr 表达式,可通过 AND/OR 逻辑组合多个条件。
delayobject延迟请求的配置。abortdelay 至少需要配置其中一个。
delay.durationnumber延迟时长(秒),可以为小数。配置 delay 时必填。
delay.percentageinteger[0, 100]被延迟的请求占比。若同时配置了 vars,则两个条件都必须满足。
delay.varsarray[]延迟请求前需匹配的规则。支持 lua-resty-expr 表达式,可通过 AND/OR 逻辑组合多个条件。

TIP

vars 支持 lua-resty-expr 表达式,可灵活实现规则之间的 AND/OR 关系。示例:

[
    [
        [ "arg_name","==","jack" ],
        [ "arg_age","==",18 ]
    ],
    [
        [ "arg_name2","==","allen" ]
    ]
]

以上示例中,前两个表达式之间是 AND 关系,而它们与第三个表达式之间是 OR 关系。

示例

下面的示例演示了如何在不同场景中在路由上配置 fault-injection

NOTE

你可以这样从 config.yaml 中获取 admin_key 并存入环境变量:

admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')

注入故障

以下示例演示如何在路由上配置 fault-injection 插件,拦截请求并以指定 HTTP 状态码响应,不转发请求到上游服务。

使用 abort 操作创建带有 fault-injection 插件的路由:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "fault-injection-route",
    "uri": "/anything",
    "plugins": {
      "fault-injection": {
        "abort": {
          "http_status": 404,
          "body": "APISIX Fault Injection"
        }
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'

向路由发送请求:

curl -i "http://127.0.0.1:9080/anything"

你应该收到 HTTP/1.1 404 Not Found 响应,并看到以下响应体,请求不会被转发到上游服务:

APISIX Fault Injection

注入延迟

以下示例演示如何在路由上配置 fault-injection 插件以注入请求延迟。

使用 delay 操作创建带有 fault-injection 插件的路由,将响应延迟 3 秒:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "fault-injection-route",
    "uri": "/anything",
    "plugins": {
      "fault-injection": {
        "delay": {
          "duration": 3
        }
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'

向路由发送请求,并使用 time 计时:

time curl -i "http://127.0.0.1:9080/anything"

你应该收到来自上游服务的 HTTP/1.1 200 OK 响应,计时摘要应显示约 3 秒总耗时:

real    0m3.034s
user    0m0.007s
sys     0m0.010s

条件注入故障

以下示例演示如何在路由上配置 fault-injection 插件,仅在满足特定请求条件时注入故障。

创建带有 fault-injection 插件的路由,配置仅当 URL 参数 name 等于 john 时才终止请求:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "fault-injection-route",
    "uri": "/anything",
    "plugins": {
      "fault-injection": {
        "abort": {
          "http_status": 404,
          "body": "APISIX Fault Injection",
          "headers": {
            "X-APISIX-Remote-Addr": "$remote_addr"
          },
          "vars": [
            [
              [ "arg_name","==","john" ]
            ]
          ]
        }
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'

发送 URL 参数 namejohn 的请求:

curl -i "http://127.0.0.1:9080/anything?name=john"

你应该收到类似以下的 HTTP/1.1 404 Not Found 响应:

HTTP/1.1 404 Not Found
...
X-APISIX-Remote-Addr: 192.168.65.1

APISIX Fault Injection

发送 name 为其他值的请求:

curl -i "http://127.0.0.1:9080/anything?name=jane"

你应该收到来自上游服务的 HTTP/1.1 200 OK 响应,没有注入故障。