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
1 ➜ test 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
13 ➜ test 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
-
查看日志结果
通过启动关停 flask server, 再查看 nginx $upstream_addr 字段的值,看看 nginx 不同情况记录什么内容。
结论,当有一个可用的服务的时候,upstream_addr 记录的是这个可用后端的 ip:port; 非动态注册(测试用例就是写死的 upstream),Nginx 会去重试连接那些失效 server,此时 upstream_addr 显示多个值,尝试链接了多少个,就逗号分割记录多少个; 当关停所有 flask 后,upstream_addr 显示为“backend-servers”,即 upstream 后面定义的名字,出现这个,表明没有一个可用的后端服务,问题大了,服务彻底不可啦!
版权申明:
- 未标注来源的内容全部为原创,未经授权请勿转载(因转载后排版往往错乱、内容不可控、无法持续更新等);
- 非营利为目的,演绎本博客任何内容,请以'原文出处'或者'参考链接'等方式给出本站相关网页地址(方便读者)。