社区的问题
OpenResty 相比于 Nginx 的一大优点就是动态特性。社区上有人问想要在 404 的时候重试上游应该如何实现。 事实上这个功能 nginx 自身也可以实现,只不过 OpenResty 可以更加灵活的控制请求。
如何实现
想要动态控制上游就需要使用 balancer_by_lua* 这个指令。
为了实现 404 时候的重试,需要 nginx 的 proxy_next_upstream 指令来配合。
当然 proxy_next_upstream_tries 和 proxy_next_upstream_timeout 两个指令也值得考虑。
不过 proxy_next_upstream_tries
也可以不配置,通过 Lua 接口来控制。
配置 proxy_next_upstream
指令的时候需要特别注意,如果业务本身是 POST
请求,但是还想要重试,
那么 应该加上 non_idempotent
这个参数。
配置案例
下面给从相关的重点配置,这里面虽然没有判断上游的结果是不是 404,但是给出了判断的途径。
既通过 ngx.var.upstream_status
获取上游的返回状态。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
upstream backend {
server 0.0.0.1;
balancer_by_lua_block {
local balancer = require "ngx.balancer"
local host = "127.0.0.2"
local port = 80
if ngx.ctx.upstream_retries == nil then
ngx.ctx.upstream_retries = 1
balancer.set_more_tries(1)
else
ngx.ctx.upstream_retries = ngx.ctx.upstream_retries + 1
host = "127.0.0.3"
-- ngx.log(ngx.INFO, "upstream status: ", ngx.var.upstream_status)
end
local ok, err = balancer.set_current_peer(host, port)
if not ok then
ngx.log(ngx.ERR, "failed to set the current peer: ", err)
return ngx.exit(500)
end
}
keepalive 10; # connection pool
}
server {
location /test404 {
proxy_next_upstream error timeout http_404;
proxy_pass http://backend;
}
}
思考题
如果重试上游的时候需要使用不同的参数,那么又该如何处理呢?
这个时候就得派上我们的 recreate_request.
有空我们再给一个案例。