Page MenuHomePhabricator

ATS: align ATS and Gerrit Apache timeouts to reenable connection re-use
Closed, ResolvedPublic

Description

When the Gerrit web service has been switched behind ATS, we witnessed git fetches failing with HTTP 502 errors (T417536).

@Vgutierrez found out that is caused by ATS reusing connections and its timeout of 120 seconds cause it to reuse connections that are are about to be closed by the backend.

ATS connection re-use has been disabled by operations/puppet #1239888, quoting Valentin:

We observed gerrit going away after receiving a request from ATS on certain occasions triggering 502s responses.
This could be related to connection re-use or keep-alive timeout desync.

My interpretation T417536#11622959:

Apache on Gerrit has the default Debian configuration:

# allow persistent connections
KeepAlive On
# No more than 100 requests for a connection
MaxKeepAliveRequests 100
# Wait 5 seconds for another request before closing
KeepAliveTimeout 5

Can it be that ATS has a much longer timeout than the Apache 5 seconds timeout? If so i imagine:

  • ATS picks up a connection that it considers not having timed out (idling less than whatever timeout it has) but is about to expire on the Apache side (it has been idle for almost 5 seconds).
  • ATS sends the headers and at the same time, because the connection has been idling for 5 seconds Apache terminates it (tcp FIN?)
  • ATS gets the unexpected termination, gives up and emit a 502 response

Thus if ATS reuses a connection that has been idling for next to 5 seconds on the Gerrit side, it emits a packet there (ATS timeout is 120 s so it considers the connection fine to use) and by the time the packet make it, Gerrit has closed the connection. A FIN is replied, ATS consider the backend to fail and emits a 502.

ATS does retry, but not POST requests and the git fetch do use POST are thus not retries.

When we switched Gerrit from eqiad to codfw, the increased latency between ATS and Gerrit caused the more connections to fall in the gap and the issue happens way more frequently.

Action items

From Valentin:

  • Gerrit Apache 2 KeepAliveTimeout needs to be synced with ATS value (120s)
  • MaxKeepAliveRequests probably needs to be set to 0

You probably want to do this after moving away from public IPs for gerrit backends or at least after closing port 443 to the Internet

Related Objects

Event Timeline

Change #1240197 had a related patch set uploaded (by Arnaudb; author: Arnaudb):

[operations/puppet@production] gerrit: adapt httpd config to ATS

https://gerrit.wikimedia.org/r/1240197

Change #1240197 had a related patch set uploaded (by Hashar; author: Arnaudb):

[operations/puppet@production] gerrit: adapt httpd config to ATS

https://gerrit.wikimedia.org/r/1240197

Change #1240294 had a related patch set uploaded (by Arnaudb; author: Arnaudb):

[operations/puppet@production] gerrit: add gerrit-replica service to LVS

https://gerrit.wikimedia.org/r/1240294

Change #1240603 had a related patch set uploaded (by Arnaudb; author: Arnaudb):

[operations/puppet@production] gerrit: add gerrit-replica backend to LVS

https://gerrit.wikimedia.org/r/1240603

Change #1240294 abandoned by Jelto:

[operations/puppet@production] gerrit: add gerrit-replica service to LVS

Reason:

not needed

https://gerrit.wikimedia.org/r/1240294

Change #1240603 merged by Jelto:

[operations/puppet@production] trafficserver: Add gerrit-replica backend

https://gerrit.wikimedia.org/r/1240603

ABran-WMF changed the task status from Stalled to In Progress.Mar 5 2026, 1:33 PM

Change #1251092 had a related patch set uploaded (by Arnaudb; author: Arnaudb):

[operations/puppet@production] gerrit: sync httpd config to ATS

https://gerrit.wikimedia.org/r/1251092

Change #1240197 abandoned by Arnaudb:

[operations/puppet@production] gerrit: sync httpd config to ATS

Reason:

rebase gone wrong, change replicated in 1251092

https://gerrit.wikimedia.org/r/1240197

Change #1251092 merged by Arnaudb:

[operations/puppet@production] gerrit: sync httpd config to ATS

https://gerrit.wikimedia.org/r/1251092

Change #1253268 had a related patch set uploaded (by Arnaudb; author: Arnaudb):

[operations/puppet@production] trafficserver: Enable connection re-use for gerrit-spare

https://gerrit.wikimedia.org/r/1253268

Before merging the CDN config change for gerrit-spare I've been able to run:

cd /tmp \
&& git clone --depth=1 https://gerrit-spare.wikimedia.org/r/mediawiki/extensions.git \
&& cd extensions \
&& sed -i s/gerrit.wikimedia.org/gerrit-spare.wikimedia.org/g .gitmodules \
&& git submodule update --init --depth=3 --jobs=5 \
&& cd /tmp/ \
&& rm -rf extensions

with no error. I'll merge the CDN config change and try that again before moving on to the replica instance

Change #1253268 merged by Arnaudb:

[operations/puppet@production] trafficserver: Enable connection re-use for gerrit-spare

https://gerrit.wikimedia.org/r/1253268

Change #1253279 had a related patch set uploaded (by Arnaudb; author: Arnaudb):

[operations/puppet@production] trafficserver: Enable connection re-use for gerrit-replica

https://gerrit.wikimedia.org/r/1253279

the httpd config update to align httpd on ATS has also been applied to gerrit-replica

Change #1253279 merged by Arnaudb:

[operations/puppet@production] trafficserver: Enable connection re-use for gerrit-replica

https://gerrit.wikimedia.org/r/1253279

Change #1253376 had a related patch set uploaded (by Arnaudb; author: Arnaudb):

[operations/puppet@production] trafficserver: Enable connection re-use for gerrit

https://gerrit.wikimedia.org/r/1253376

The httpd config update has been applied to all hosts.
The CDN config change looks OK for both spare and replica.

Change #1253376 merged by Arnaudb:

[operations/puppet@production] trafficserver: Enable connection re-use for gerrit

https://gerrit.wikimedia.org/r/1253376

Configs have been applied to the primary instance and its CDN backend.

Change #1253396 had a related patch set uploaded (by Arnaudb; author: Arnaudb):

[operations/puppet@production] trafficserver: disable connection re-use for gerrit

https://gerrit.wikimedia.org/r/1253396

this change applied to the primary instance has caused a huge slow down, reverting

Change #1253396 merged by Jelto:

[operations/puppet@production] trafficserver: disable connection re-use for gerrit

https://gerrit.wikimedia.org/r/1253396

closing that task, we've aligned ATS and httpd timeouts, the debug effort of Gerrit's UI slowing down will be tracked in T420189: Gerrit: Debug connection re-use on Gerrit's httpd causing Gerrit interface to be very slow

Cool!

Since timeouts between ATS and httpd have been aligned; now would be the next step to align timeouts between httpd and jetty (Gerrit's webserver).

That would be to merge https://gerrit.wikimedia.org/r/c/operations/puppet/+/1241048 which seems good to me and I +1ed.

This would re-resolve old ticket T246763

it's merged! I'll resolve T246763: Jenkins job failing intermittently due to Gerrit HTTP 502 errors when interacting with repos. Thanks for pointing out that commit.

In T420189: Gerrit: Debug connection re-use on Gerrit's httpd causing Gerrit interface to be very slow there is no real traces of that increased slowness in the logs, but it looked like it stemmed from Jetty.
I'll rollout the change that slowed our primary Gerrit down to a halt again in the coming days to see if these changes help with the sluggishness.

Reopening as Stalled given the ATS connection reuse for the Gerrit primary has been enabled and then rolled back. The troubleshooting is happening in the sub task T420189.

@ABran-WMF and I had a long debugging session last Thursday which I have summarized in at T420189#11732690 and following comments.

The issue is Gerrit was switched behind the CDN without Envoy as an intermediary proxy. When the keepalive got raised from 5 seconds to 120 seconds, Gerrit Apache httpd suddenly had to handle a lot more TCP connections. The pool of TCP listeners in the MPM event has been raised by setting AsyncRequestWorkerFactor 8 which allows maintaining a lot more keepalived TCP connections.

/etc/apache2/conf-enabled/10-connection-reuse.conf:KeepAlive On
/etc/apache2/conf-enabled/10-connection-reuse.conf:MaxKeepAliveRequests 0
/etc/apache2/conf-enabled/10-connection-reuse.conf:KeepAliveTimeout 122

The connection re-use remains disabled. Given httpd now has a timeout larger than the ATS 120s, it is no more going to close connections ATS is about to use. Therefore I guess we can reenable connection reuse.

As a follow up, we probably should introduce Envoy in between CDN and httpd to align with other services and maybe switch httpd MPM from event to worker (since keep alive connections would be handled by Envoy).

The connection-reuse was enabled as part of introducing Envoy between the CDN and Gerrit (https://gerrit.wikimedia.org/r/1259945). That is the bit that was missing when the service was migrated and was the cause of the 502 outage we witnessed a few weeks ago.