修改一下Nginx的配置:
server { ...... location / { proxy_pass :5556; # 修改一个不存在的端口 proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; } ...... }我们这里把后端指向了一个后端服务器不存在的端口,然后通过浏览器访问,你会马上得到502状态码,错误日志信息为“connect() failed (111: Connection refused)”。
情况三:这种情况不好模拟,这时候就不能用之前的flask框架的程序了,需要自己写一个套接字程序,代码如下:
#!/usr/bin/env python # -*- coding: utf-8 -*- import socket import os, time, sys import signal def echoStr(connFd, sleep_time): print("新连接:", connFd.getpeername()) sleep_time = sleep_time print("睡眠 %s 秒后返回数据" % sleep_time) time.sleep(sleep_time) try: with open("./index.html", "r") as f1: html_data = f1.read() connFd.send(html_data.encode(encoding="utf-8")) except Exception as err: print(err) def main(): sockFd = socket.socket() sockFd.bind(("", 5555)) sockFd.listen(5) signal.signal(signal.SIGCHLD, sigChld) print("等待客户端连接......") while True: connFd, remAddr = sockFd.accept() try: # 10 是传递进去的睡眠时间 echoStr(connFd, 10) connFd.close() except Exception as err: print(err) if __name__ == '__main__': main()启动程序python3 ./mysocket.py
然后使用浏览器访问,依然是通过Nginx做代理,Nginx无需修改,在10秒内CTRL+C来终止程序,这时候相当于是向套接字发送RES:
查看Nginx日志:
看看抓包情况
前面部分都和情况一相同,但是你注意最后一个箭头,它是[R.]而且方向是从50到40方向,也就是后端给Nginx发的,这就是我在程序收到请求以后按了CTRL+C终止了程序,这就等于向双方建立的套接字发送了RST,当Nginx尝试去读一个已经收到RST的套接字的时候就会得到ECONNRESET错误,当然如果是写操作也会得到这个ECONNRESET。
我这里使用CTRL+C和情况一中不同,同样的操作但是对于套接字的影响不同,这是因为你在套接字编程的时候一定需要考虑进程崩溃怎么办、网络临时抖动怎么办,flask框架里面的web服务是有这些机制的,当它收到终止操作信号的时候会做哪些后续处理,我们看到它是通过正常机制来完成了四次端口,而反观我自己写的这个简易Socket程序没有任何其他考虑,收到终止信号后直接就发送了RST。
小结针对Nginx在什么情况下产生502我们找到3种:
代理到一个不存在的端口,记住这里是端口,不是地址。 在error_log中显示 connect() failed (111: Connection refused) 访问日志出现502,
后端终止了程序,但正常完成了四次断开,error_log中显示 permaturely closed connection。
后端终止了程序,但没有完成四次端开而是发送了RST,error_log中显示 recv() failed (104: Connection reset by peer)
实验3:状态码504(Gateway Timeout) 情况一:这个就是Nginx超时导致的,我们修改一下Nginx配置:
server { ...... location / { proxy_pass :5555; proxy_set_header host ; proxy_connect_timeout 60s; proxy_read_timeout 5s; # 修改为5秒 proxy_send_timeout 60s; # proxy_ignore_client_abort on; } ...... }我们把proxy_read_timeout改成了5秒,这样Nginx等待后端回传数据只能5秒,因为我们后端是10秒后响应。然后重新reload配置。之后启动我们的Flask程序进行访问测试:
通过浏览器访问,并观察Nginx日志
这个原因就是Nginx的proxy_read_timeout超时时长小于,后端处理时长。
我这个例子是把read改为5秒,造成读超时,其实对于proxy_send_timeout也一样,如果写超时也是也是504.
情况二:这个就需要修改的地方会多一些,我们一点一点来
修改Nginx主机的/etc/hosts文件,添加一条,如下:
192.168.10.50