Skip to main content
Version: Next

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 响应,没有注入故障。