When implementing Comet-style long polling with Tomcat 6.0.24 (JDK 1.6) behind an Amazon ELB, the keep-alive timeout setting isn't being respected. Despite configuring a 330-second (5.5 minute) timeout in the HTTPS connector, connections are being terminated prematurely at exactly 65 seconds.
The environment consists of:
OS: Ubuntu
Web Server: Tomcat 6.0.24
Java: JDK 1.6
Protocol: HTTPS (non-APR connector)
Load Balancer: Amazon ELB
Packet capture reveals the following sequence:
T=0 Client → Server: SYN (handshake initiation)
T=65 Server → Client: FIN (connection termination)
T=307 Client → Server: FIN (client-side cleanup)
The 65-second timeout is actually imposed by Amazon ELB's idle timeout setting, which defaults to 60 seconds. The extra 5 seconds comes from TCP-level timeouts. This setting overrides any application-level configuration.
You need to modify both your ELB configuration and Tomcat settings:
1. Update ELB Configuration
Increase the idle timeout through AWS CLI:
aws elb modify-load-balancer-attributes \
--load-balancer-name your-elb-name \
--load-balancer-attributes "{\"ConnectionSettings\":{\"IdleTimeout\":300}}"
2. Adjust Tomcat Configuration
Ensure your connector is properly configured:
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="1000" keepAliveTimeout="330000"
connectionTimeout="360000" maxKeepAliveRequests="-1"
scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />
- Confirm ELB settings via AWS console or CLI
- Test with
curl -v
to verify connection duration - Check Tomcat access logs for connection duration
- Use TCP dump for network-level verification
- ELB maximum timeout is 4000 seconds
- Consider TCP keepalive settings at OS level
- Monitor for increased resource usage with longer timeouts
When implementing Comet-style long polling with Tomcat 6.0.24 behind an Amazon Elastic Load Balancer (ELB), many developers encounter an issue where HTTPS connections are being closed after exactly 65 seconds, despite setting a higher keepAliveTimeout
value in the Tomcat connector configuration.
The 65-second timeout is actually imposed by the ELB's idle timeout setting, which defaults to 60 seconds (plus some buffer time). This setting overrides any keep-alive configuration you've set in Tomcat when the ELB is in the path.
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="1000" keepAliveTimeout="330000"
scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />
For AWS Classic Load Balancer:
- Go to EC2 Console → Load Balancers
- Select your load balancer
- Click the "Listener" tab
- Click "Edit" and set the "Idle Timeout" to your desired value (up to 3600 seconds)
For Application Load Balancer (ALB):
aws elbv2 modify-load-balancer-attributes \
--load-balancer-arn your-lb-arn \
--attributes Key=idle_timeout.timeout_seconds,Value=300
If you need even longer timeouts, consider using TCP load balancing instead of HTTPS:
# Nginx configuration example for TCP passthrough
stream {
server {
listen 443;
proxy_pass tomcat_backend;
proxy_timeout 300s;
}
upstream tomcat_backend {
server tomcat1:8443;
server tomcat2:8443;
}
}
After making changes, verify with tcpdump
:
sudo tcpdump -i any -nn -s 0 -w elb_test.pcap port 8443
Or using openssl
to test the connection:
openssl s_client -connect your-elb:8443 -quiet
# Wait and observe when connection closes
- Longer timeouts consume more resources on both ELB and Tomcat
- Monitor connection counts and memory usage
- Consider implementing heartbeat mechanisms for very long polls
- For WebSocket connections, use ALB with proper protocol support