Skip to content

Commit 94f55f7

Browse files
authored
bugfix: respect max retry after using balancer pool.
In the balancer phase, when obtaining a connection from the upstream connection pool, the `cached` attribute of the peer connection is set to 1(`pc->cached = 1;`), indicating that the connection is obtained from the cache. If an error occurs during the use of this connection, such as "upstream prematurely closed connection" the system will increase the `tries` attribute of the peer connection by executing `u->peer.tries++`. This PR restores tries by callbacks to the balancer when `u->peer.tries++` is unexpectedly set. Signed-off-by: tzssangglass <[email protected]>
1 parent 0a1c704 commit 94f55f7

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed

src/ngx_http_lua_balancer.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ static ngx_int_t ngx_http_lua_balancer_by_chunk(lua_State *L,
8787
ngx_http_request_t *r);
8888
static void ngx_http_lua_balancer_free_peer(ngx_peer_connection_t *pc,
8989
void *data, ngx_uint_t state);
90+
static void ngx_http_lua_balancer_notify_peer(ngx_peer_connection_t *pc,
91+
void *data, ngx_uint_t type);
9092
static void ngx_http_lua_balancer_close(ngx_connection_t *c);
9193
static void ngx_http_lua_balancer_dummy_handler(ngx_event_t *ev);
9294
static void ngx_http_lua_balancer_close_handler(ngx_event_t *ev);
@@ -365,6 +367,7 @@ ngx_http_lua_balancer_init_peer(ngx_http_request_t *r,
365367
r->upstream->peer.data = bp;
366368
r->upstream->peer.get = ngx_http_lua_balancer_get_peer;
367369
r->upstream->peer.free = ngx_http_lua_balancer_free_peer;
370+
r->upstream->peer.notify = ngx_http_lua_balancer_notify_peer;
368371

369372
#if (NGX_HTTP_SSL)
370373
bp->original_set_session = r->upstream->peer.set_session;
@@ -737,6 +740,18 @@ ngx_http_lua_balancer_free_peer(ngx_peer_connection_t *pc, void *data,
737740
}
738741

739742

743+
static void
744+
ngx_http_lua_balancer_notify_peer(ngx_peer_connection_t *pc, void *data,
745+
ngx_uint_t type)
746+
{
747+
#ifdef NGX_HTTP_UPSTREAM_NOTIFY_CACHED_CONNECTION_ERROR
748+
if (type == NGX_HTTP_UPSTREAM_NOTIFY_CACHED_CONNECTION_ERROR) {
749+
pc->tries--;
750+
}
751+
#endif
752+
}
753+
754+
740755
static void
741756
ngx_http_lua_balancer_close(ngx_connection_t *c)
742757
{
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# vim:set ft= ts=4 sw=4 et:
2+
3+
use Test::Nginx::Socket::Lua;
4+
use Cwd qw(cwd);
5+
6+
log_level('info');
7+
repeat_each(1);
8+
9+
plan tests => repeat_each() * (blocks() * 6);
10+
11+
my $pwd = cwd();
12+
13+
no_long_string();
14+
15+
check_accum_error_log();
16+
run_tests();
17+
18+
__DATA__
19+
20+
=== TEST 1: sanity
21+
--- http_config
22+
lua_shared_dict request_counter 1m;
23+
upstream my_upstream {
24+
server 127.0.0.1;
25+
balancer_by_lua_block {
26+
local balancer = require "ngx.balancer"
27+
28+
if not ngx.ctx.tries then
29+
ngx.ctx.tries = 0
30+
end
31+
32+
ngx.ctx.tries = ngx.ctx.tries + 1
33+
ngx.log(ngx.INFO, "tries ", ngx.ctx.tries)
34+
35+
if ngx.ctx.tries == 1 then
36+
balancer.set_more_tries(5)
37+
end
38+
39+
local host = "127.0.0.1"
40+
local port = 8090;
41+
42+
local ok, err = balancer.set_current_peer(host, port)
43+
if not ok then
44+
ngx.log(ngx.ERR, "failed to set the current peer: ", err)
45+
return ngx.exit(500)
46+
end
47+
48+
balancer.set_timeouts(60000, 60000, 60000)
49+
50+
local ok, err = balancer.enable_keepalive(60, 100)
51+
if not ok then
52+
ngx.log(ngx.ERR, "failed to enable keepalive: ", err)
53+
return ngx.exit(500)
54+
end
55+
}
56+
}
57+
58+
server {
59+
listen 0.0.0.0:8090;
60+
location /hello {
61+
content_by_lua_block{
62+
local request_counter = ngx.shared.request_counter
63+
local first_request = request_counter:get("first_request")
64+
if first_request == nil then
65+
request_counter:set("first_request", "yes")
66+
ngx.print("hello")
67+
else
68+
ngx.exit(ngx.HTTP_CLOSE)
69+
end
70+
}
71+
}
72+
}
73+
--- config
74+
location = /t {
75+
proxy_pass http://my_upstream;
76+
proxy_set_header Connection "keep-alive";
77+
78+
rewrite_by_lua_block {
79+
ngx.req.set_uri("/hello")
80+
}
81+
}
82+
--- pipelined_requests eval
83+
["GET /t HTTP/1.1" , "GET /t HTTP/1.1"]
84+
--- response_body eval
85+
["hello", qr/502/]
86+
--- error_code eval
87+
[200, 502]
88+
--- no_error_log eval
89+
qr/tries 7/

0 commit comments

Comments
 (0)