nginx

【nginx】nginx log 中$upstream_addr

2023-03-04  本文已影响0人  Bogon

nginx $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.

$ cat /etc/nginx/conf.d/test.com.conf

upstream backend-servers{
        server 127.0.0.1:9527;
        server 127.0.0.1:9528;
        server 127.0.0.1:9529;
}

server {
        listen 80;
        server_name www.test.com;

        access_log /va/log/test.com.log access;

        location / {
                proxy_pass http://backend-servers;
        }
}

当有一个可用的服务的时候,upstream_addr记录的是这个可用后端的ip:port;

非动态注册(测试用例就是写死的upstream),nginx会去重试连接那些失效server,此时upstream_addr显示多个值,尝试链接了多少个,就逗号分割记录多少个;

当关停所有后端实例后,upstream_addr显示为“backend-servers”,即upstream定义的名字,出现这个,表明没有一个可用的后端服务

10.19.42.241######-######-######[20/Feb/2023:11:09:16 +0800]######"GET /version-control/xxx HTTP/1.1"######404######568######"-"######"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36; Qing/0.0.7; App/test 10086/4.1.0; 4.1.0 (2212151455); deviceId:b68aad8776277d5e930239ceac59a2d6; clientId:10086;lang:zh-CN;bno:4.1.0(2212151455);"######0.000######www.test.com######b4340dccb2e797b626a6139e4862a546######upstest01######502######-######http######0.000######-######901


10.19.42.234######-######-######[20/Feb/2023:09:57:17 +0800]######"POST /gateway/xxx HTTP/1.1"######404######568######"-"######"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36; Qing/0.0.7; App/test 10086/4.1.0; 4.1.0 (2212151455); deviceId:d283d1e27e540cfdd8e13e3f2d56a562; clientId:10086;lang:zh-CN;bno:4.1.0(2212151455);"######0.000######www.test.com######0ebb7d08ada07e02c89726bed3b04392######upstest02######502######-######http######0.000######-######1047

client <---> nginx <--- > upstream

分析nginx日志,发现 :

  1. $upstream_addr 字段出现的是 upstream后面定义的名字
  2. upstream 给 nginx返回的 http_code 为 502
  3. nginx 给 client 返回的 http_code 为 404

从nginx log 中$upstream_addr 字段输出upstream的名称 ,不对劲 应该响应的是 某个实例的 ip:port

为什么会直接返回 upstream的名称呢? 那是因为nginx检测后端发现没有存活可以用的 实例

明明后端实例都存活的啊,nginx为什么认为他们都不可用呢?

原因是在一个存活检测周期里,nginx向后端建立连接临时端口不够用了,大量处于 TIME-WAIT的 tcp连接占据了本地端口,来不及释放,那么在这个 存活检测周期里,你没有排到号。。。nginx 就认为 没有存活的 upstream 实例!

查看nginx服务器tcp连接状态:

ss  -s  

ss -tan | awk '{++S[$1]} END {for(a in S) print a, S[a]}'
 
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
image.png

解决方法:

  1. 增加nginx 服务器数量
  1. 调优nginx服务器内核参数,增加对临时端口的复用能力

# vim  /etc/sysctl.conf
###########################
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_timestamps = 1
############################

# sysctl  -p

如果你后续想将上面的 内核参数改回来,改为:


net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_timestamps = 0

端口不复用 ,改为 复用 nginx可以不重启;正在复用,突然改为不复用。。。已存在的连接会怎样?

听哥一句,修改完sysctl -p 之后一定要 重启nginx进程,不只是 reload ,不然你会发现,所有已经建立的连接被全部reset了!!!

参考

nginx日志$upstream_addr多个值

https://mephisto.cc/tech/upstream_addr/
https://help.aliyun.com/document_detail/405072.html

nginx log输出upstream的名字
https://bbs.csdn.net/topics/393712408

上一篇下一篇

猜你喜欢

热点阅读