我们分别通过抓包(tcpdump -nni any port 80 and not net 100.64.0.0/10)和curl命令来看下:
a. 两次TCP三次握手的建连都是成功的。这说明SLB已经正确把请求转发到了后端服务器,问题不是出在SLB。
b. 接着往应用层的包去看,既然返回结果不同,那么请求的参数必然有所不同。比较后发现,二者的区别在于Host字段不同,导致请求的URI不同。这似乎跟我们的报错信息就能联系上了。(请求的资源不存在)
Hypertext Transfer Protocol
GET / HTTP/1.1\r\n
[Expert Info (Chat/Sequence): GET / HTTP/1.1\r\n]
Request Method: GET
Request URI: /
Request Version: HTTP/1.1
Host: mubi.pier39.cn\r\n <---
User-Agent: curl/7.79.1\r\n
X-True-IP: 140.205.147.111\r\n
X-Real-IP: 140.205.147.111\r\n
Web-Server-Type: nginx\r\n
WL-Proxy-Client-IP: 140.205.147.111\r\n
X-Forwarded-For: 140.205.147.111\r\n
X-Forwarded-Proto: http\r\n
EagleEye-TraceId: 0bca315a16571825606783394e0182\r\n
Accept: */*\r\n
eagleeye-rpcid: 0.1\r\n
x5-uuid: 6304a34f9e75bb29cd9fd955c2846a5a\r\n
\r\n
[Full request URI: http://mubi.pier39.cn/]
[HTTP request 1/1]
[Response in frame: 15]
Hypertext Transfer Protocol
GET / HTTP/1.1\r\n
[Expert Info (Chat/Sequence): GET / HTTP/1.1\r\n]
Request Method: GET
Request URI: /
Request Version: HTTP/1.1
Host: mubi.pier39.cn:8080\r\n <---
User-Agent: curl/7.79.1\r\n
Accept: */*\r\n
\r\n
[Full request URI: http://mubi.pier39.cn:8080/]
[HTTP request 1/1]
[Response in frame: 26]
c. 如何验证我们的想法是正确的呢?这里可以使用curl命令修改一下HTTP的请求头,测试结果如下:
chenxiaoying@B-GG9JML7H-2306 ~ curl -v -H Host:mubi.pier39.cn http://mubi.pier39.cn:8080
* Trying 47.103.21.135:8080...
* Connected to mubi.pier39.cn (47.103.21.135) port 8080 (#0)
> GET / HTTP/1.1
> Host:mubi.pier39.cn
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
a. location, location字段主要用于匹配Request URI,用于展示不同的页面.
b. server_name, 推荐看一下这篇官方文档 How nginx processes a request。简单来说,server_name的作用就是nginx服务会检查request header 的host字段来决定由哪个server块来handle这个请求。看这个描述,还是很符合我们的问题的。于是修改为server_name mubi.pier39.cn mubi.pier39.cn:8080,很可惜,问题仍未解决.
c. 在没有思路的情况下,查看日志往往是我们的唯一选择。根据教程把nginx debug log开启,注意这里最好把SLB的健康检查暂时关闭,否则会收到海量的日志。从日志中我们看到,在抛出301状态码之前,是fastcgi模块在工作。因此将怀疑对象锁定在了fastcgi。
问题描述
i-uf6gu2e9qpdvh21rirul为一台Wordpress服务器,搭建方法参考 https://help.aliyun.com/document_detail/151691.html 其通过SLB lb-uf67nwk3l117mkje02h0y 对外提供服务。 现给SLB配置TCP四层监听,监听8080端口,后端虚拟服务器组为i-uf6gu2e9qpdvh21rirul,暴露80端口。 SLB的公网IP解析到mubi.pier39.cn域名。 问题:通过http://mubi.pier39.cn:8080访问时报错返回502。
排查过程
HTTP 301:
这里可以尝试把SLB的80端口也监听到后端服务器的80端口,该问题就会消失。但是这并没有真正解决我们的问题。
我们分别通过抓包(tcpdump -nni any port 80 and not net 100.64.0.0/10)和curl命令来看下: a. 两次TCP三次握手的建连都是成功的。这说明SLB已经正确把请求转发到了后端服务器,问题不是出在SLB。 b. 接着往应用层的包去看,既然返回结果不同,那么请求的参数必然有所不同。比较后发现,二者的区别在于Host字段不同,导致请求的URI不同。这似乎跟我们的报错信息就能联系上了。(请求的资源不存在)
c. 如何验证我们的想法是正确的呢?这里可以使用curl命令修改一下HTTP的请求头,测试结果如下:
a. location, location字段主要用于匹配Request URI,用于展示不同的页面. b. server_name, 推荐看一下这篇官方文档 How nginx processes a request。简单来说,server_name的作用就是nginx服务会检查request header 的host字段来决定由哪个server块来handle这个请求。看这个描述,还是很符合我们的问题的。于是修改为server_name mubi.pier39.cn mubi.pier39.cn:8080,很可惜,问题仍未解决. c. 在没有思路的情况下,查看日志往往是我们的唯一选择。根据教程把nginx debug log开启,注意这里最好把SLB的健康检查暂时关闭,否则会收到海量的日志。从日志中我们看到,在抛出301状态码之前,是fastcgi模块在工作。因此将怀疑对象锁定在了fastcgi。
d. 如何验证我们的想法是正确的呢?可以改写nginx的配置文件,去除掉处理php的这块配置。可以发现服务器就能正确返回对mubi.pier39.cn:8080的请求了。 e. 综合我们前面的分析,问题大概率出在fastcgi param HTTP_HOST这里 2022/07/07 23:11:51 [debug] 13008#0: *81 fastcgi param: "HTTP_HOST: mubi.pier39.cn:8080" <---- 因此我们的想法就是需要手动指定HTTP_HOST,而不是让fastcgi由http请求去自动获取。 fastcgi_param HTTP_HOST mubi.pier39.cn; 添加上述配置后,问题恢复。