Drain connections on restart of NGINX process?
I'm using NGINX 1.8.1 on CentOS 6 and 7. During our deploys, it is required that NGINX is stopped, the deploy executes, and NGINX starts again. Unfortunately, NGINX during a stop seems to just 500 all connections. As I'm using Ansible to update 2/10 hosts at a time, it's likely therefore that many of our clients will get 500'd throughout our deploy process.
Is there a way via NGINX settings to have the NGINX process drain all live connections (ie wait for them to complete) while rejecting all new connections during a stop?
I know that Amazon's Elastic Load Balancers do have this functionality, is there an equivalent for NGINX?
Solution 1:
According to the comments, you could try to solve this using a firewall:
Task: Block incoming new connections, but keep related and established ones
Try:
iptables -I INPUT -j DROP -p tcp --syn --destination-port 80
(or 443, whatever applies to your setup) to set the rule, thus blocking new trafficDo your deployment...
Try:
iptables -D INPUT -j DROP -p tcp --syn --destination-port 80
(or 443, whatever applies to your setup) to revert the rule, thus allowing new trafficNote: I've just tested this shortly, it worked as expected. But: Please don't take this for granted, and test for yourself as well. Feedback welcome...
Edit: As @Guntram Blohm pointed out in the comments, better to use iptables -I
instead of iptables -A
. Changed this appropriately in the above code.
Solution 2:
Send nginx the "QUIT" signal to perform a graceful shutdown, which stops listening for new connections but allows workers to continue to serve active connections.
It's worth distinguishing between graceful shutdown and connection draining; graceful shutdown affects how NGINX deals with incoming connections while the server is shutting down, but connection draining (which as Martijn Heemels mentioned is a feature of NGINX Plus) deals with how NGINX removes a backend server from service when acting as a load balancer. From your question, it sounds like you're more interested in the former.
Solution 3:
As far as I can tell, connection draining is only available in the commercial version, Nginx Plus.
There's a description of the feature here: https://www.nginx.com/blog/nginx-plus-r5-released/
It's part of the ngx_http_upstream_conf_module module.