Nginx was configured as reverse proxy for an upstream server that servers a website. Upon checking the setup I encountered the 502 Bad gateway error. In Nginx error.log
I found the following line:
1 |
*1 upstream prematurely closed connection while reading response header from upstream, client: 127.0.0.1, server: , request: "GET /check HTTP/1.1", upstream: "http://127.0.0.1:4005/check", host: "example.com" |
I spent some time playing around with a config but the right direction for digging was found once I examined the outgoing package:
1 2 3 4 5 6 7 8 9 |
2020/09/01 15:25:22.949364 length=241 from=0 to=240 GET /check HTTP/1.0\r Host: upstream.server\r Connection: close\r User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:68.0) Gecko/20100101 Firefox/68.0\r Accept-Language: en-US,en;q=0.5\r Upgrade-Insecure-Requests: 1\r Cache-Control: max-age=0\r \r |
The fourth line "Connection: close\r"
showed that Nginx sends Connection: close
header to the upstream server so the connection is terminated.
So what we need is to keep alive the connection between Nginx and upstream server.
For HTTP (like in my case) the proxy_http_version directive should be set to “1.1” and the “Connection” header field should be cleared:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
upstream http_backend { server 127.0.0.1:8080; keepalive 16; } server { ... location /http/ { proxy_pass http://http_backend; proxy_http_version 1.1; proxy_set_header Connection ""; ... } } |
Alternatively, HTTP/1.0
persistent connections can be used by passing the "Connection: Keep-Alive"
header field to an upstream server, though this method is not recommended.
Adding the
1 2 |
proxy_http_version 1.1; proxy_set_header Connection ""; |
directives solved my problem and 502 Bad gateway error was fixed.
Example configuration of memcached upstream with keepalive connections:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
upstream memcached_backend { server 127.0.0.1:11211; server 10.0.0.2:11211; keepalive 32; } server { ... location /memcached/ { set $memcached_key $uri; memcached_pass memcached_backend; } } |
For FastCGI servers, it is required to set fastcgi_keep_conn
for keepalive connections to work:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
upstream fastcgi_backend { server 127.0.0.1:9000; keepalive 8; } server { ... location /fastcgi/ { fastcgi_pass fastcgi_backend; fastcgi_keep_conn on; ... } } |
When using load balancer methods other than the default round-robin method, it is necessary to activate them before the keepalive
directive.
SCGI and uwsgi protocols do not have a notion of keepalive connections.
Good luck!