这个确实比较复杂
如果你的场景都是小请求,性能要求不高,可以接受 ngx.location.capture 的话
把所有的重试逻辑都放到 lua 里面来搞,这是一个相对容易搞的思路
client -[1]-> nginx proxy <--[2]--> 站点A(302)
|[3]
V
站点B (返回500)
比如以上图,客户端请求 nginx proxy_pass 到站点A, 站点A返回302, 然后nginx再proxy_pass到站点B
这时如果站点B返回500、504等之类的话,nginx需要继续重试请求站点B,如果重试几次访问不了,就返回到站点A获取新的302信息,继续proxy_pass到站点B
location ~* / {
proxy_intercept_errors on;
error_page 302 = @redirect_page_302;
}
location @redirect_page_302{
}
如果到站点B就返回200,那这样就可以了,但是还要对proxy_pass返回的状态码判断,如果是504,500,那还要再继续proxy_pass 到站点B
用ngx.location.capture的话,要访问外部站点B,还是得要写proxy_pass
location @redirect_page_302{
access_by_lua_block {
local res = ngx.location.capture("/error_retry")
ngx.say(res.status)
if res.status ~= ngx.HTTP_OK then
local res = ngx.location.capture("/error_retry")
ngx.say("error_retry: number ",ngx.var.count)
end
}
}
location /error_retry {
internal;
proxy_pass http://xxxxxx; proxy_pass 到站点B
} 如果设置重试次数,并在达到次数后,再请求站点A,站点A又返回302,那怎样重复使用前面得302跳转,没有很好的思路