I have a fairly simple AWS Elastic Beanstalk setup (Rails on Puma, with NGINX) and get intermittent but quite regular 504 Gateway Time-out on the client (typically 10 seconds after making the request). The requests that fail are quite simple, so should not be timing out.
NGINX acts as a reverse proxy to the Puma app server running on the same instance, and provides TLS termination. There are two Beanstalk managed EC2 instances with this setup, behind the standard Beanstalk configured AWS application load balancer (ALB). The load balancer also terminates the TLS connection before passing it on to NGINX.
browser (443) ---> (443) ALB (443) ---> | (443) NGINX (socket)-> Puma |
I have followed the AWS troubleshooting: https://aws.amazon.com/premiumsupport/knowledge-center/504-error-alb/
All this really confirms is that the monitoring shows HTTPCode_ELB_5XX counts, which indicates the 504 error originated from the load balancer. No 50x errors are coming back from NGINX. I have checked the ALB logs, and they show that the 504 error occurs, but is unrelated to any specific target. The request never makes it to a target backend. The monitoring does show target connection errors.
I have a specific NGINX server config, with the only real related settings (within the server {...}
block) being:
ssl_session_timeout 5m;
client_max_body_size 20M;
proxy_read_timeout 300;
client_header_timeout 75;
client_body_timeout 75;
keepalive_timeout 75;
The ALB configuration has Idle timeout 60 seconds
The EC2s show only about 50% memory utilization and low CPU.
I have also spent some time looking at: https://sigopt.com/blog/the-case-of-the-mysterious-aws-elb-504-errors/ which led me to look into keepalives, etc, and Wireshark. In summary, NGINX shows that a client ALB closed a connection. Soon after, sometimes I'll get a 504 in the browser. This is typically 10 seconds later, and corresponds with the ALB not being able to get a return from a target. But there is no reason why the targets should not respond, and they are not even being touched. It is almost like a security groups issue just very occasionally blocking a request, but these either work or they don't.
The app servers are already prewarmed by the time these errors occur, and there are no CPU spikes when the failures happen.
I know that the application runs fine on a single instance beanstalk without an ALB in front of it, so we can rule out app performance for this discussion.
Any help or suggestions would be much appreciated.