Nginx日志$upstream_addr多个值

最近在排查一个线上问题的时候,发现 nginx 日志$upstream_addr 字段居然返回了 2 个值,形如"192.168.1.1:80, api-servers",其中 api-servers 是指代的是你的 upstream 后面接 group name,部分只有一个值"api-servers"。正常情况下,这个地方应该是类似“192.168.1.1:80”这样,即一个请求落到一个后端服务。

查询官方文档:

$upstream_addr

keeps the IP address and port, or the path to the UNIX-domain socket of the upstream server. If several servers were contacted during request processing, their addresses are separated by commas, e.g. “192.168.1.1:80, 192.168.1.2:80, unix:/tmp/sock”. If an internal redirect from one server group to another happens, initiated by “X-Accel-Redirect” or error_page, then the server addresses from different groups are separated by colons, e.g. “192.168.1.1:80, 192.168.1.2:80, unix:/tmp/sock : 192.168.10.1:80, 192.168.10.2:80”. If a server cannot be selected, the variable keeps the name of the server group.

细读上面的文档,当请求尝试链接了多个后端服务器的时候,上述逗号分割多值记录的情况就会发生,冒号分割是另外一种状况,这里不讨论。当值为 server group name 的时候,“If a server cannot be selected” 这英文表意不明,写这个文档的人英文应该不是母语,是所有后端不可用,还是在默认限定的选择数目内都不可用,有知道的高手可以探讨下。总之,如果你的服务是注册到 upstream 里面的,服务池里面的服务,此时应该是不可用了,要自己去排错,多值记录给了你个线索。

在我们的场景中,是使用 consul 注册服务的,判定为某个机房的 consul 集群异常了,导致旧的服务没有被摘除,新的也没有及时更新,落到旧服务的请求没有可用的 server, 返回 502 状态码。

昨天对这个有疑问,今天来测试验证。

1. Nginx 配置

 1    ➜  cat /etc/nginx/conf.d/test.com.conf
 2    upstream backend-servers{
 3            server 127.0.0.1:9527;
 4            server 127.0.0.1:9528;
 5            server 127.0.0.1:9529;
 6            server 127.0.0.1:9530;
 7            server 127.0.0.1:9531;
 8            server 127.0.0.1:9532;
 9            server 127.0.0.1:9533;
10            server 127.0.0.1:9534;
11            server 127.0.0.1:9535;
12            server 127.0.0.1:9536;
13            server 127.0.0.1:9537;
14            server 127.0.0.1:9538;
15            server 127.0.0.1:9539;
16            server 127.0.0.1:9540;
17            server 127.0.0.1:9541;
18            server 127.0.0.1:9542;
19            server 127.0.0.1:9543;
20            server 127.0.0.1:9544;
21            server 127.0.0.1:9545;
22            server 127.0.0.1:9546;
23            server 127.0.0.1:9547;
24            server 127.0.0.1:9548;
25            server 127.0.0.1:9549;
26            server 127.0.0.1:9550;
27            server 127.0.0.1:9551;
28            server 127.0.0.1:9552;
29            server 127.0.0.1:9552;
30            server 127.0.0.1:9553;
31            server 127.0.0.1:9554;
32            server 127.0.0.1:9555;
33            server 127.0.0.1:9556;
34            server 127.0.0.1:9557;
35            server 127.0.0.1:9558;
36            server 127.0.0.1:9559;
37            server 127.0.0.1:9560;
38            server 127.0.0.1:9561;
39            server 127.0.0.1:9562;
40    }
41    server {
42            listen 80;
43            server_name test.com;
44
45            access_log /data/log/test.com.log access;
46
47            location /{
48                    proxy_pass http://backend-servers;
49            }
50    }

2. 用 Flask 模拟运行 backend-server

 1test cat server1.py
 2    from flask import Flask
 3
 4    app = Flask(__name__)
 5
 6    @app.route("/")
 7    def hello_world():
 8        return "<p>Hello, 9527!</p>"
 9
10    if __name__ == '__main__':
11        app.run(host="0.0.0.0", port=9527)
12
13test cat server2.py
14    from flask import Flask
15
16    app = Flask(__name__)
17
18    @app.route("/")
19    def hello_world():
20        return "<p>Hello, 9528!</p>"
21
22    if __name__ == '__main__':
23        app.run(host="0.0.0.0", port=9528)
24``
25
26如下图所示
27
28![flask server](/images/flask-server.webp)
29
30### 3. 测试抓包查看日志验证
31
32- 用命令 curl 测试
33
34```shell
35curl -H "Host:test.com" http://127.0.0.1
  • tcpdump 抓包看 nginx 是否会连接失效的 backend-server
1sudo tcpdump -i lo port 9528
  • 查看日志结果

    nginx upstream test

    通过启动关停 flask server, 再查看 nginx $upstream_addr 字段的值,看看 nginx 不同情况记录什么内容。

结论,当有一个可用的服务的时候,upstream_addr 记录的是这个可用后端的 ip:port; 非动态注册(测试用例就是写死的 upstream),Nginx 会去重试连接那些失效 server,此时 upstream_addr 显示多个值,尝试链接了多少个,就逗号分割记录多少个; 当关停所有 flask 后,upstream_addr 显示为“backend-servers”,即 upstream 后面定义的名字,出现这个,表明没有一个可用的后端服务,问题大了,服务彻底不可啦!

最后修改于: Wednesday, February 21, 2024
欢迎关注微信公众号,留言交流。

相关文章:

翻译: