状況
- Nginxでserverにproxyして通信する際、
一定確率でNginxとserverでTCPコネクションが確立されず、NginxがHTTP_statuscode502を返す事象が発生していた。
今回行ったこと
- TCPコネクションを切断するstubを作成して再現させ、対処法を考えた
検証
stub_server
nginx config
upstream stub {
server 172.31.27.174:8000 max_fails=0;
server 172.31.27.174:8000 max_fails=0;
server 172.31.27.174:8000 max_fails=0;
}
server {
listen 80;
server_name 172.31.27.174;
charset utf-8;
location / {
proxy_pass http://stub/;
proxy_next_upstream http_500;
}
}
stub program
- stubの処理を3種類にわけ、randomで処理を行うようにした
- HTTP_response(status_code=200)を返す
- HTTP_response(status_code=500)を返す
- TCPコネクション切断。
import socket
import random
STUB_PORT = 8000
print "waiting now"
serversock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversock.bind(('', STUB_PORT))
serversock.listen(100)
while True:
soc, addr = serversock.accept()
soc.recv(50000)
method = random.choice(["200","500","error"])
if method == "200":
soc.send("HTTP/1.1 200 OK\r\nCache-Control: no-cache, private\r\nContent-Length: 0\r\nDate: Fri, 17 Feb 2018 10:21:21 GMT\r\n\r\n")
elif method == "500":
soc.send("HTTP/1.1 500 InternalServerError\r\nCache-Control: no-cache, private\r\nContent-Length: 0\r\nDate: Fri, 17 Feb 2018 10:21:21 GMT\r\n\r\n")
else:
soc.close()
response集計用script
import requests
status_code200 = 0
status_code500 = 0
error_response = 0
for i in range(100):
r = requests.get('http://54.250.242.76/stub/')
if r.status_code == 200:
status_code200 += 1
elif r.status_code == 500:
status_code500 += 1
else:
error_response += 1
print "status_code200 : " + str(status_code200)
print "status_code500 : " + str(status_code500)
print "error_response : " + str(error_response)
集計結果
status_code200 : 48
status_code500 : 4
error_response : 48
↓POINT↓
改修方法(nginx)
- proxy_next_upstream に
error
を追加する
- TCPコネクションでerrorが起こってもretryしコネクションを確立させようとする
upstream stub {
server 172.31.27.174:8000 max_fails=0;
server 172.31.27.174:8000 max_fails=0;
server 172.31.27.174:8000 max_fails=0;
}
server {
listen 80;
server_name 172.31.27.174;
charset utf-8;
location / {
proxy_pass http://stub/;
proxy_next_upstream http_500 error;
}
}
改修後の集計結果
status_code200 : 69
status_code500 : 16
error_response : 15