Skip to content

Commit 314edfd

Browse files
authored
fix: running stale healthchecker when new node count <= 1 (#12118)
1 parent 05f9e48 commit 314edfd

File tree

4 files changed

+116
-6
lines changed

4 files changed

+116
-6
lines changed

apisix/upstream.lua

+2-4
Original file line numberDiff line numberDiff line change
@@ -359,10 +359,8 @@ function _M.set_by_route(route, api_ctx)
359359
return 503, err
360360
end
361361

362-
if nodes_count > 1 then
363-
local checker = fetch_healthchecker(up_conf)
364-
api_ctx.up_checker = checker
365-
end
362+
local checker = fetch_healthchecker(up_conf)
363+
api_ctx.up_checker = checker
366364

367365
local scheme = up_conf.scheme
368366
if (scheme == "https" or scheme == "grpcs") and up_conf.tls then

docs/en/latest/tutorials/health-check.md

-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ Since unhealthy nodes cannot receive requests, nodes cannot be re-marked as heal
5252

5353
- We only start the health check when the upstream is hit by a request. There won't be any health check if an upstream is configured but isn't in used.
5454
- If there is no healthy node can be chosen, we will continue to access the upstream.
55-
- We won't start the health check when the upstream only has one node, as we will access it whether this unique node is healthy or not.
5655

5756
:::
5857

docs/zh/latest/tutorials/health-check.md

-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ description: 本文介绍了如何使用 API 网关 Apache APISIX 的健康检
5151

5252
- 只有在 `upstream` 被请求时才会开始健康检查,如果 `upstream` 被配置但没有被请求,不会触发启动健康检查。
5353
- 如果没有健康的节点,那么请求会继续发送给上游。
54-
- 如果 `upstream` 中只有一个节点时不会触发启动健康检查,该唯一节点无论是否健康,请求都将转发给上游。
5554

5655
:::
5756

t/discovery/reset-healthchecker.t

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one or more
3+
# contributor license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright ownership.
5+
# The ASF licenses this file to You under the Apache License, Version 2.0
6+
# (the "License"); you may not use this file except in compliance with
7+
# the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
use t::APISIX 'no_plan';
19+
20+
repeat_each(1);
21+
log_level('info');
22+
no_root_location();
23+
no_shuffle();
24+
workers(1);
25+
26+
27+
28+
29+
add_block_preprocessor(sub {
30+
my ($block) = @_;
31+
if (!$block->request) {
32+
$block->set_value("request", "GET /t");
33+
}
34+
if ($block->apisix_yaml) {
35+
my $upstream = <<_EOC_;
36+
upstreams:
37+
- service_name: mock
38+
discovery_type: mock
39+
type: roundrobin
40+
checks:
41+
active:
42+
http_path: /
43+
timeout: 1
44+
unhealthy:
45+
tcp_failures: 30
46+
interval: 1
47+
healthy:
48+
interval: 1
49+
id: 1
50+
#END
51+
_EOC_
52+
53+
$block->set_value("apisix_yaml", $block->apisix_yaml . $upstream);
54+
}
55+
});
56+
57+
run_tests();
58+
59+
__DATA__
60+
61+
=== TEST 1: Validate healthchecker recreation on node count reduces to 1
62+
--- http_config
63+
server {
64+
listen 3000 ;
65+
location / {
66+
return 200 'ok';
67+
}
68+
}
69+
--- apisix_yaml
70+
routes:
71+
-
72+
uris:
73+
- /
74+
upstream_id: 1
75+
--- config
76+
location /t {
77+
content_by_lua_block {
78+
local t = require("lib.test_admin").test
79+
local discovery = require("apisix.discovery.init").discovery
80+
discovery.mock = {
81+
nodes = function()
82+
return {
83+
{host = "127.0.0.1", port = 3000, weight = 50},
84+
{host = "127.0.0.1", port = 8000, weight = 50},
85+
}
86+
end
87+
}
88+
local http = require "resty.http"
89+
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/"
90+
local httpc = http.new()
91+
local res, err = httpc:request_uri(uri, {method = "GET", keepalive = false})
92+
ngx.sleep(5)
93+
discovery.mock = {
94+
nodes = function()
95+
return {
96+
{host = "127.0.0.1", port = 3000, weight = 1}
97+
}
98+
end
99+
}
100+
local http = require "resty.http"
101+
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/"
102+
local httpc = http.new()
103+
local res, err = httpc:request_uri(uri, {method = "GET", keepalive = false})
104+
ngx.say(res.body)
105+
ngx.sleep(5)
106+
}
107+
}
108+
--- request
109+
GET /t
110+
--- response_body
111+
ok
112+
--- timeout: 22
113+
--- no_error_log
114+
unhealthy TCP increment (10/30)

0 commit comments

Comments
 (0)