Skip to content

Commit 1e7953c

Browse files
authored
fix: etcd should add another retry when no endpoints healthy (#133)
1 parent 06f9821 commit 1e7953c

File tree

2 files changed

+65
-5
lines changed

2 files changed

+65
-5
lines changed

lib/resty/etcd/v3.lua

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@ local refresh_jwt_token
3535
local function choose_endpoint(self)
3636
local endpoints = self.endpoints
3737
local endpoints_len = #endpoints
38-
if endpoints_len == 1 then
39-
return endpoints[1]
40-
end
4138

4239
if health_check.conf ~= nil then
4340
for _, endpoint in ipairs(endpoints) do
@@ -144,7 +141,7 @@ local function _request_uri(self, method, uri, opts, timeout, ignore_auth)
144141
return nil, err
145142
end
146143
else
147-
local max_retry = #self.endpoints * health_check.conf.max_fails - 1
144+
local max_retry = #self.endpoints * health_check.conf.max_fails + 1
148145
for _ = 1, max_retry do
149146
res, err = http_request_uri(self, http_cli, method, uri, body, headers, keepalive)
150147
if err then
@@ -627,7 +624,7 @@ local function request_chunk(self, method, path, opts, timeout)
627624
return nil, err
628625
end
629626
else
630-
local max_retry = #self.endpoints * health_check.conf.max_fails - 1
627+
local max_retry = #self.endpoints * health_check.conf.max_fails + 1
631628
for _ = 1, max_retry do
632629
endpoint, err = http_request_chunk(self, http_cli)
633630
if err then

t/v3/health_check.t

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ qr/update endpoint: http:\/\/127.0.0.1:42379 to unhealthy/
509509
checked val as expect: abc
510510
511511
512+
512513
=== TEST 13: test if retry works for request_chunk
513514
--- http_config eval: $::HttpConfig
514515
--- config
@@ -564,3 +565,65 @@ qr/1:.*"created":true.*
564565
2:.*"value":"abc".*
565566
timeout/
566567
--- timeout: 5
568+
569+
570+
571+
=== TEST 14: test retry failure could return correctly
572+
--- http_config eval: $::HttpConfig
573+
--- config
574+
location /v3/auth/authenticate {
575+
content_by_lua_block { -- mock normal authenticate response
576+
ngx.print([[{
577+
body = '{"header":{"cluster_id":"17237436991929493444","member_id":"9372538179322589801","revision":"40","raft_term":"633"},"token":"KicnFPYazDaiMHBG.74"}',
578+
reason = "OK",
579+
status = 200
580+
}]])
581+
}
582+
}
583+
584+
location /v3/kv/put {
585+
content_by_lua_block { -- mock abnormal put key response
586+
ngx.status = 500
587+
ngx.print([[{
588+
body = '{"error":"etcdserver: request timed out","message":"etcdserver: request timed out","code":14}',
589+
reason = "Service Unavailable",
590+
status = 503,
591+
}]])
592+
ngx.say("this is my own error page content")
593+
ngx.exit(500)
594+
}
595+
}
596+
597+
location /t {
598+
content_by_lua_block {
599+
local health_check, err = require "resty.etcd.health_check" .init({
600+
shm_name = "etcd_cluster_health_check",
601+
fail_timeout = 10,
602+
max_fails = 3,
603+
retry = true,
604+
})
605+
606+
local etcd, err = require "resty.etcd" .new({
607+
protocol = "v3",
608+
http_host = {
609+
"http://127.0.0.1:12379",
610+
},
611+
})
612+
etcd.endpoints[1].full_prefix="http://127.0.0.1:1984/v3" -- replace the endpoint with mock
613+
etcd.endpoints[1].http_host="http://127.0.0.1:1984"
614+
615+
local res, err = etcd:set("/etcd_error", "hello")
616+
local fails = ngx.shared["etcd_cluster_health_check"]:get("http://127.0.0.1:1984")
617+
ngx.say(fails)
618+
if err ~= "has no healthy etcd endpoint available" then
619+
ngx.say(err)
620+
ngx.exit(200)
621+
end
622+
}
623+
}
624+
--- request
625+
GET /t
626+
--- error_log eval
627+
qr/update endpoint: http:\/\/127.0.0.1:1984 to unhealthy/
628+
--- response_body
629+
3

0 commit comments

Comments
 (0)