This is an automated email from the ASF dual-hosted git repository.
AlinsRan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 6125bf3b9 feat: support http_method and http_req_body in active health
checks (#13726)
6125bf3b9 is described below
commit 6125bf3b9887451456c47fb1beb693d083c25192
Author: AlinsRan <[email protected]>
AuthorDate: Thu Jul 23 21:21:31 2026 +0800
feat: support http_method and http_req_body in active health checks (#13726)
---
apisix-master-0.rockspec | 2 +-
apisix/schema_def.lua | 20 ++++--
docs/en/latest/tutorials/health-check.md | 2 +
t/plugin/ai-proxy-multi3.t | 101 +++++++++++++++++++++++++++++++
t/plugin/ai-proxy-vertex-ai.t | 2 +-
5 files changed, 119 insertions(+), 8 deletions(-)
diff --git a/apisix-master-0.rockspec b/apisix-master-0.rockspec
index 9d731ea08..314b7403e 100644
--- a/apisix-master-0.rockspec
+++ b/apisix-master-0.rockspec
@@ -42,7 +42,7 @@ dependencies = {
"lua-resty-ngxvar = 0.5.2-0",
"lua-resty-jit-uuid = 0.0.7-2",
"lua-resty-ksuid = 1.0.1-0",
- "lua-resty-healthcheck-api7 = 3.2.2-0",
+ "lua-resty-healthcheck-api7 = 3.2.3-0",
"api7-lua-resty-jwt = 0.2.6-0",
"lua-resty-hmac-ffi = 0.06-1",
"lua-resty-cookie = 0.4.1-1",
diff --git a/apisix/schema_def.lua b/apisix/schema_def.lua
index 08e67d9cb..98bf2de34 100644
--- a/apisix/schema_def.lua
+++ b/apisix/schema_def.lua
@@ -138,6 +138,14 @@ local timeout_def = {
}
+local method_schema = {
+ description = "HTTP method",
+ type = "string",
+ enum = {"GET", "POST", "PUT", "DELETE", "PATCH", "HEAD",
+ "OPTIONS", "CONNECT", "TRACE", "PURGE"},
+}
+
+
local health_checker_active = {
type = "object",
properties = {
@@ -154,7 +162,13 @@ local health_checker_active = {
minimum = 1,
maximum = 65535
},
+ http_method = {
+ type = "string",
+ enum = method_schema.enum,
+ default = "GET"
+ },
http_path = {type = "string", default = "/"},
+ http_req_body = {type = "string", default = ""},
https_verify_certificate = {type = "boolean", default = true},
healthy = {
type = "object",
@@ -553,12 +567,6 @@ _M.upstream_hash_vars_combinations_schema = {
}
-local method_schema = {
- description = "HTTP method",
- type = "string",
- enum = {"GET", "POST", "PUT", "DELETE", "PATCH", "HEAD",
- "OPTIONS", "CONNECT", "TRACE", "PURGE"},
-}
_M.method_schema = method_schema
diff --git a/docs/en/latest/tutorials/health-check.md
b/docs/en/latest/tutorials/health-check.md
index cf344a9c6..5762db1ac 100644
--- a/docs/en/latest/tutorials/health-check.md
+++ b/docs/en/latest/tutorials/health-check.md
@@ -62,7 +62,9 @@ Since unhealthy nodes cannot receive requests, nodes cannot
be re-marked as heal
| upstream.checks.active.type | Active check
| string | `http` `https` `tcp` | http
| The type of active
check.
|
| upstream.checks.active.timeout | Active check
| integer | | 1
| The timeout period
of the active check (unit: second).
|
| upstream.checks.active.concurrency | Active check
| integer | | 10
| The number of
targets to be checked at the same time during the active check.
|
+| upstream.checks.active.http_method | Active check
| string | `GET` `POST` ... | GET
| The HTTP method of
the request that is actively checked.
|
| upstream.checks.active.http_path | Active check
| string | | /
| The HTTP request
path that is actively checked.
|
+| upstream.checks.active.http_req_body | Active check
| string | |
| The request body
sent in the actively checked HTTP request (a non-empty body adds a
`Content-Length` header). |
| upstream.checks.active.host | Active check
| string | | ${upstream.node.host}
| The hostname of the
HTTP request actively checked.
|
| upstream.checks.active.port | Active check
| integer | `1` to `65535` | ${upstream.node.port}
| The host port of the
HTTP request that is actively checked.
|
| upstream.checks.active.https_verify_certificate | Active check
| boolean | | true
| Active check whether
to check the SSL certificate of the remote host when HTTPS type checking is
used. |
diff --git a/t/plugin/ai-proxy-multi3.t b/t/plugin/ai-proxy-multi3.t
index 9a7e1376d..84ef19002 100644
--- a/t/plugin/ai-proxy-multi3.t
+++ b/t/plugin/ai-proxy-multi3.t
@@ -1121,3 +1121,104 @@ trying to increment a target that is not in the list
host: 127.0.0.1
port: 443
passed
+
+
+
+=== TEST 15: create a ai-proxy-multi plugin that use post method as health
check
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local core = require("apisix.core")
+ -- build the route as a Lua table + core.json.encode: an inline
[[..]]
+ -- JSON this large trips OpenResty 1.29's config-parser
long-bracket buffer
+ local route = {
+ uri = "/ai",
+ plugins = {
+ ["ai-proxy-multi"] = {
+ fallback_strategy =
"instance_health_and_rate_limiting",
+ instances = {
+ {
+ name = "openai-gpt4", provider = "openai",
weight = 1, priority = 1,
+ auth = {
+ header = { Authorization = "Bearer token"
},
+ query = { apikey = "token_in_query" },
+ },
+ options = { model = "gpt-4" },
+ override = { endpoint =
"http://127.0.0.1:16724" },
+ checks = {
+ active = {
+ timeout = 5,
+ http_method = "POST",
+ http_path = "/post",
+ http_req_body =
"{\"model\":\"gpt-4o-mini\",\"messages\":[{\"role\":\"user\",\"content\":\"write
a haiku about ai\"}],\"stream\":false}",
+ host = "foo.com",
+ healthy = { interval = 1, successes =
1 },
+ req_headers = { "User-Agent:
curl/7.29.0" },
+ },
+ },
+ },
+ {
+ name = "openai-gpt3", provider = "openai",
weight = 1, priority = 1,
+ auth = { header = { Authorization = "Bearer
token" } },
+ options = { model = "gpt-3" },
+ override = { endpoint =
"http://127.0.0.1:16724" },
+ },
+ },
+ ssl_verify = false,
+ },
+ },
+ }
+ local code, body = t('/apisix/admin/routes/1', ngx.HTTP_PUT,
+ core.json.encode(route))
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 16: check if the health check works
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local core = require("apisix.core")
+
+ local send_request = function()
+ local code, _, body = t("/ai",
+ ngx.HTTP_POST,
+ [[{
+ "messages": [
+ { "role": "system", "content": "You are a
mathematician" },
+ { "role": "user", "content": "What is 1+1?" }
+ ]
+ }]],
+ nil,
+ {
+ ["Content-Type"] = "application/json",
+ }
+ )
+ assert(code == 200, "request should be successful")
+ return body
+ end
+
+ -- trigger the health check
+ send_request()
+ ngx.sleep(3)
+ ngx.say("passed")
+ }
+ }
+--- response_body
+passed
+--- error_log
+probe method: POST
+probe authorization header: Bearer token
+probe apikey query: token_in_query
+probe content-length: 102
+probe body: {"model":"gpt-4o-mini","messages":[{"role":"user","content":"write
a haiku about ai"}],"stream":false}
diff --git a/t/plugin/ai-proxy-vertex-ai.t b/t/plugin/ai-proxy-vertex-ai.t
index 88a6c2aa7..a7740abcb 100644
--- a/t/plugin/ai-proxy-vertex-ai.t
+++ b/t/plugin/ai-proxy-vertex-ai.t
@@ -446,7 +446,7 @@ X-AI-Fixture: openai/chat-basic.json
qr/"content"\s*:\s*"1 \+ 1 = 2\."/
--- error_log
creating healthchecker for upstream
-request head: GET /status/gpt4
+request: GET /status/gpt4