Skip to content

Commit

Permalink
feature: health check supports custom host port. (#1914)
Browse files Browse the repository at this point in the history
  • Loading branch information
shuaijinchao authored Jul 28, 2020
1 parent 4015071 commit 520ef31
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 7 deletions.
17 changes: 10 additions & 7 deletions apisix/balancer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,10 @@ local function fetch_health_nodes(upstream, checker)
end

local host = upstream.checks and upstream.checks.active and upstream.checks.active.host
local port = upstream.checks and upstream.checks.active and upstream.checks.active.port
local up_nodes = core.table.new(0, #nodes)
for _, node in ipairs(nodes) do
local ok = checker:get_target_status(node.host, node.port, host)
local ok = checker:get_target_status(node.host, port or node.port, host)
if ok then
-- TODO filter with metadata
up_nodes[node.host .. ":" .. node.port] = node.weight
Expand Down Expand Up @@ -93,11 +94,12 @@ local function create_checker(upstream, healthcheck_parent)
})

local host = upstream.checks and upstream.checks.active and upstream.checks.active.host
local port = upstream.checks and upstream.checks.active and upstream.checks.active.port
for _, node in ipairs(upstream.nodes) do
local ok, err = checker:add_target(node.host, node.port, host)
local ok, err = checker:add_target(node.host, port or node.port, host)
if not ok then
core.log.error("failed to add new health check target: ", node.host, ":", node.port,
" err: ", err)
core.log.error("failed to add new health check target: ", node.host, ":",
port or node.port, " err: ", err)
end
end

Expand Down Expand Up @@ -195,14 +197,15 @@ local function pick_server(route, ctx)
if checker and ctx.balancer_try_count > 1 then
local state, code = get_last_failure()
local host = up_conf.checks and up_conf.checks.active and up_conf.checks.active.host
local port = up_conf.checks and up_conf.checks.active and up_conf.checks.active.port
if state == "failed" then
if code == 504 then
checker:report_timeout(ctx.balancer_ip, ctx.balancer_port, host)
checker:report_timeout(ctx.balancer_ip, port or ctx.balancer_port, host)
else
checker:report_tcp_failure(ctx.balancer_ip, ctx.balancer_port, host)
checker:report_tcp_failure(ctx.balancer_ip, port or ctx.balancer_port, host)
end
else
checker:report_http_status(ctx.balancer_ip, ctx.balancer_port, host, code)
checker:report_http_status(ctx.balancer_ip, port or ctx.balancer_port, host, code)
end
end

Expand Down
5 changes: 5 additions & 0 deletions apisix/schema_def.lua
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ local health_checker = {
timeout = {type = "number", default = 1},
concurrency = {type = "integer", default = 10},
host = host_def,
port = {
type = "integer",
minimum = 1,
maximum = 65535
},
http_path = {type = "string", default = "/"},
https_verify_certificate = {type = "boolean", default = true},
healthy = {
Expand Down
1 change: 1 addition & 0 deletions doc/health-check.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ contains: `active` or `passive`.

* `active.http_path`: The HTTP GET request path used to detect if the upstream is healthy.
* `active.host`: The HTTP request host used to detect if the upstream is healthy.
* `active.port`: The customize health check host port (optional), this will override the port in the `upstream` node.

The threshold fields of `healthy` are:
* `active.healthy.interval`: Interval between health checks for healthy targets (in seconds), the minimum is 1.
Expand Down
1 change: 1 addition & 0 deletions doc/zh-cn/health-check.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f13

* `active.http_path`: 用于发现upstream节点健康可用的HTTP GET请求路径。
* `active.host`: 用于发现upstream节点健康可用的HTTP请求主机名。
* `active.port`: 用于发现upstream节点健康可用的自定义主机端口(可选),配置此项会覆盖 `upstream` 节点中的端口。

`healthy`的阀值字段:
* `active.healthy.interval`: 健康的目标节点的健康检查间隔时间(以秒为单位),最小值为1。
Expand Down
172 changes: 172 additions & 0 deletions t/node/healthcheck.t
Original file line number Diff line number Diff line change
Expand Up @@ -621,3 +621,175 @@ GET /t
qr/^.*?\[warn\].*/
--- grep_error_log_out eval
qr/unhealthy TCP increment.*foo.com/



=== TEST 14: add route (test health check customized `port`)
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"uri": "/server_port",
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1,
"127.0.0.1:1981": 1
},
"checks": {
"active": {
"http_path": "/status",
"port": 1988,
"host": "foo.com",
"healthy": {
"interval": 1,
"successes": 1
},
"unhealthy": {
"interval": 1,
"http_failures": 2
}
}
}
}
}]]
)

if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed



=== TEST 15: test health check customized `port`
--- config
location /t {
content_by_lua_block {
local http = require "resty.http"
local uri = "http://127.0.0.1:" .. ngx.var.server_port
.. "/server_port"

local httpc = http.new()
local res, err = httpc:request_uri(uri, {method = "GET", keepalive = false})

ngx.sleep(2)

ngx.say(res.status)
}
}
--- request
GET /t
--- response_body
200
--- grep_error_log eval
qr/^.*?\[warn\].*/
--- grep_error_log_out eval
qr/unhealthy TCP increment.*foo.com.*127.0.0.1:1988/



=== TEST 16: add route (test health check customized `port` out of minimum range)
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"uri": "/server_port",
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1,
"127.0.0.1:1981": 1
},
"checks": {
"active": {
"http_path": "/status",
"port": 0,
"host": "foo.com",
"healthy": {
"interval": 1,
"successes": 1
},
"unhealthy": {
"interval": 1,
"http_failures": 2
}
}
}
}
}]]
)

if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /t
--- response_body_like eval
qr/expected 0 to be greater than 1/
--- error_code chomp
400



=== TEST 17: add route (test health check customized `port` out of maximum range)
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"uri": "/server_port",
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1,
"127.0.0.1:1981": 1
},
"checks": {
"active": {
"http_path": "/status",
"port": 65536,
"host": "foo.com",
"healthy": {
"interval": 1,
"successes": 1
},
"unhealthy": {
"interval": 1,
"http_failures": 2
}
}
}
}
}]]
)

if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /t
--- response_body_like eval
qr/expected 65536 to be smaller than 65535/
--- error_code chomp
400

0 comments on commit 520ef31

Please sign in to comment.