...

HTTP Keep-Alive timeout: optimale configuratie voor serverprestaties

Met de focus op HTTP Keep-Alive time-out Ik laat je zien hoe je inactieve tijden kunt instellen zodat verbindingen worden hergebruikt zonder threads te blokkeren. Ik leg specifieke waarden uit, laat typische valkuilen zien en geef beproefde configuraties voor nginx, Apache en het besturingssysteem.

Centrale punten

  • SaldoTe kort verhoogt handdrukken, te lang blokkeert draden.
  • WaardenMeestal 5-15 s en 100-500 aanvragen per verbinding.
  • CoördinatieCoördineer time-outs van client, LB en firewall.
  • Speciale gevallenWebSockets, SSE, Long Polling afzonderlijk.
  • ControleOpen sockets, FD's en latenties bewaken.

HTTP Keep-Alive kort uitgelegd

Ik houd TCP-verbindingen met Keep-Alive open zodat meerdere verzoeken dezelfde regel gebruiken. Dit bespaart me herhaalde TCP en TLS handshakes en vermindert de CPU-overhead merkbaar. Dit is vooral handig voor veel kleine bestanden zoals pictogrammen, JSON of CSS. Elke nieuwe verbinding die wordt vermeden, vermindert contextwisselingen en ontlast kernelroutines. In benchmarks met een hoog aandeel GET wordt de totale duur aanzienlijk verkort omdat er minder SYN/ACK pakketten worden gegenereerd en er meer rekentijd naar de applicatielogica vloeit.

Ik meet snel het effect: bewegende gemiddelde latencies worden vloeiender en het aantal nieuwe TCP-verbindingen per seconde daalt. Ik bereik dit niet door magie, maar door Hergebruik van verbindingen en verstandige limieten. Het blijft belangrijk dat Keep-Alive geen vervanging is voor snelle rendering of caching. Het verkort de wachttijden aan de netwerkgrens, terwijl de app zelf efficiënt moet blijven reageren. Beide samen verhogen de Prestaties merkbaar.

De juiste time-out begrijpen

De time-out bepaalt hoe lang een inactieve verbinding open blijft staan voordat de server deze sluit. sluit. Als ik het te kort instel, openen clients constant nieuwe TCP-verbindingen, wat Overhead wordt verhoogd. Als ik het te lang instel, parkeren ongebruikte verbindingen kostbare werkers of threads. De kunst ligt in de balans tussen hergebruik en resourceverbruik. Ik test praktisch: stel het eerst ruw in en stel het dan nauwkeurig af met belastingstesten.

Ik let ook op de relatie tussen responstijden en inactieve vensters. Als de typische gebruikersinteractie tussen twee klikken 2-4 seconden is, dan dekt een time-out van 5-15 seconden meestal het echte patroon. Korte API-oproepen kunnen gemakkelijk 5-10 seconden verdragen, mediawerklasten 10-15 seconden. Het is belangrijk dat ik niet overdrijf: buitensporig lange time-outs leiden zelden tot meer Doorvoer, maar leiden vaak tot geblokkeerde Bronnen. Ik kan dit snel herkennen aan het toenemende aantal open stopcontacten en hoge FD-cijfers.

Time-outs netjes scheiden

Ik maak een strikt onderscheid tussen Time-out inactief (Keep-Alive), Time-out lezen/header (hoe lang de server wacht op inkomende verzoeken) en Time-out verzenden/schrijven (hoe lang het sturen naar de klant wordt getolereerd). Deze categorieën vervullen verschillende taken:

  • Time-out inactief: Regelt het hergebruik en de parkeerduur van inactieve verbindingen.
  • Time-out lezen/header: Beschermt tegen langzame clients (slow lorises) en halfverzonden headers.
  • Time-out verzenden/schrijven: Voorkomt dat de server eindeloos moet wachten op een trage ontvangst bij de client.

Op nginx Ik gebruik bewust header_timeout/read_timeout en send_timeout per context (http/server/locatie) naast keepalive_timeout. Sinds nieuwere versies stel ik optioneel keepalive_tijd, om de maximale levensduur van een verbinding te beperken, zelfs als deze actief blijft. In Apache Ik gebruik ook RequestReadTimeout (mod_reqtimeout) en controleer Time-out (globaal) los van KeepAliveTimeout. Deze scheiding is een belangrijke bouwsteen tegen het vastleggen van middelen zonder echt voordeel.

Aanbevolen waarden in de praktijk

Voor productieve omgevingen stel ik een keep-alive timeout in van 5-15 seconden en 100-500 verzoeken per verbinding. Dit bereik zorgt voor een goed hergebruik van verbindingen en houdt het aantal slapende verbindingen laag. Op nginx Ik gebruik keepalive_timeout 10s als startwaarde en keepalive_requests 200. Als er veel verkeer is, verhoog ik deze gematigd als ik te veel nieuwe TCP-verbindingen zie. Als er weinig verkeer is, verlaag ik het weer om een vloedgolf van inactief verkeer te voorkomen.

Degenen die dieper gaan, hebben baat bij een duidelijk afstemmingsproces met meetpunten. Hiervoor vat ik mijn richtlijnen samen in een praktische gids die het pad beschrijft van meten naar configureren naar regelen. Voor een snelle start verwijs ik je naar mijn stappen in Keep-Alive-tuning. Hoe kunt u Hergebruik en limieten en voorkom verrassingen. Wat uiteindelijk telt is een lage latency met stabiele Doorvoer.

Risico's van lange time-outs

Een lange time-out houdt verbindingen kunstmatig open en blokkeert werkers ook al volgt er geen verzoek. Dit zorgt ervoor dat sockets opzwellen en het aantal bestandsdescriptors opdrijft. Als het proces zijn grenzen bereikt, zie ik afwijzende accept fouten of wachtrijen bij het opzetten van een verbinding. Het geheugen groeit, garbage collectors of allocators kosten extra tijd en de latentie neemt toe. In het geval van een fout sturen clients dan naar sockets die al gesloten zijn en ontvangen cryptische Fout.

Ik voorkom dit door gematigde waarden in te stellen en regelmatig de metriek te controleren. Als ongebruikte verbindingen te veel toenemen bij lage belasting, verlaag ik de time-out. Als ik veel nieuwe verbindingen per seconde zie tijdens verkeerspieken, verhoog ik de timeout voorzichtig in kleine stapjes. Zo houd ik de Capaciteit bruikbaar en voorkomen dode verbindingen. Het resultaat is een soepeler systeem met minder Tips in de bochten.

Configuratie: nginx, Apache en OS-laag

Ik begin op het niveau van de webserver en stel de time-out en limieten in. Op nginx Ik stel keepalive_timeout 5-15s in en keepalive_requests 100-500. In Apache met event-MPM combineer ik KeepAlive On, KeepAliveTimeout 5-15 en MaxKeepAliveRequests 100-500. Vervolgens kalibreer ik worker- of threadpools aan de hand van de verwachte belasting. Dit voorkomt dat inactieve keep-alives productief worden. Slots binden.

Ik verhoog limieten en wachtrijen op besturingssysteemniveau. Ik stel ulimit -n in op minstens 100.000, pas net.core.somaxconn en tcp_max_syn_backlog aan en controleer de TIME_WAIT afhandeling. Dit zorgt ervoor dat de kernel en het proces genoeg Bronnen bieden. Tot slot controleer ik de paden van de NIC via IRQ-balancing naar de app. Hierdoor kan ik tijdig knelpunten herkennen en de Latency laag.

Component Richtlijn/instelling Aanbeveling Tip
nginx keepalive_timeout 5–15 s Kortere met weinig verkeer, langer met veel kleine verzoeken
nginx keepalive_requests 100–500 Recycleert verbindingen en vermindert Lekken
Apache (gebeurtenis) KeepAliveTimeout 5–15 s Event-MPM beheert inactiviteit efficiënter dan prefork
Besturingssysteem ulimit -n ≥ 100.000 Meer open FD's voor velen Sockets
Besturingssysteem net.core.somaxconn Verhogen Minder afgewezen verbindingen onder Piekbelasting

Reverse proxy en upstream hergebruik

Ik denk altijd keep-alive end-to-end. Achter de edge server zit vaak een keten van reverse proxy → app servers. Voor nginx activeer ik mijn eigen Keep Alive Zwembaden (upstream keepalive, keepalive_requests, keepalive_timeout), stel proxy_http_version 1.1 in en verwijder „Connection: close“. Dit bespaart me ook intern handshakes en offload app backends (Node.js, Java, PHP-FPM). In Apache met mod_proxy behoud ik ook persistente verbindingen naar backendservers en beperk ze per bestemming zodat een hotspot de pools niet monopoliseert.

Ik meet afzonderlijk: Hergebruiksnelheid Client→Edge en Edge→Backend. Als ik goed hergebruik zie aan de rand, maar veel nieuwe verbindingen naar de backend, verhoog ik selectief de upstream pools. Hierdoor kan ik schalen zonder globaal de timeouts van de frontend te verhogen.

Werkers, threads en OS-limieten

Ik dimensioneer workers, events en threads niet volgens gewenste waarden, maar volgens lastprofiel. Om dit te doen, monitor ik actieve verzoeken, inactieve werkers, gebruik van event loops en contextwisselingen. Als threads in idle geparkeerd staan, verlaag ik de time-out of de max-idle-per-thread limieten. Als ik de hele tijd 100 procent CPU zie, controleer ik de accept queues, IRQ distributie en netwerkstack. Kleine correcties aan FD limieten en backlogs maken vaak een groot verschil. Effecten.

Ik plan de headroom realistisch. Een reserve van 20-30 procent in threads en FD's biedt zekerheid voor pieken. Als ik te veel doe, verlies ik caches en neemt de verspilling toe. Als ik te weinig doe, belanden verzoeken in wachtrijen of verlopen ze. De juiste kruising van Capaciteit en efficiëntie houdt latenties laag en beschermt de Stabiliteit.

Time-outs van clients, loadbalancers en firewalls coördineren

Ik stel tijdslimieten in langs het hele pad zodat er geen doodlopende paden zijn. Verbindingen worden aangemaakt. Clients sluiten idealiter minimaal eerder af dan de server. De loadbalancer mag niet korter afsluiten, anders zie ik onverwachte resets. Ik neem NAT en firewall idle waarden op zodat verbindingen niet verloren gaan in het netwerkpad. verdwijn. Deze afstemming voorkomt heruitzendingen en vlakt de belastingscurven af.

Ik houd de keten begrijpelijk met duidelijke diagrammen: Client → LB → webserver → app. Ik documenteer idle timeouts, read/write timeouts en retry strategieën voor elke link. Als ik een waarde verander, controleer ik de buren. Dit houdt het pad consistent en geeft me reproduceerbare meetresultaten. Deze discipline bespaart tijd in de Problemen oplossen en verhoogt de betrouwbaarheid.

Beveiliging: Bescherming tegen langzame lorries en misbruik in het niets

Te ruime time-outs Aanvaloppervlakken. Daarom stel ik limieten in die legitiem hergebruik toestaan, maar het moeilijker maken om ze kwaadwillend open te houden. In nginx helpen header en read_timeout, request_headers_size limieten en een harde bovengrens voor keepalive_requests. In Apache gebruik ik mod_reqtimeout en beperk ik parallelle verbindingen per IP. Snelheidslimieten en limit_conn in nginx beschermen ook tegen overstromingen van veel inactieve sockets. Voor langlopende eindpunten maak ik aparte dedicated pools zodat aanvallen op streams de reguliere API-werkers niet ophouden.

Speciale gevallen: Long Polling, SSE en WebSockets

Langstromende stromen botsen met korte Time-outs en hebben hun eigen regels nodig. Ik scheid deze eindpunten technisch van de klassieke API en asset routes. Voor SSE en WebSockets stel ik hogere timeouts, dedicated worker pools en harde limieten per IP in. Ik houd de verbinding in leven met heartbeats of ping/pong en herken verbroken verbindingen snel. Op deze manier blokkeren streams geen threads voor gewone Korte verzoeken.

Ik beperk gelijktijdige verbindingen en meet actief. Te hoge limieten verbruiken FD's en RAM. Te strakke limieten sluiten legitieme gebruikers af. Ik vind de goede plek met schone statistieken voor open, inactieve, actieve en verbroken verbindingen. Deze scheiding bespaart me wereldwijd Verhoogt de time-outs en beschermt de Capaciteit.

HTTP/2, multiplexing en keep-alive

HTTP/2 multiplexed verschillende streams via een Aansluiting, maar blijft afhankelijk van timeouts. Ik houd het idle window gematigd omdat sessies ook onder HTTP/2 kunnen parkeren. Hoge keepalive_requests zijn hier minder belangrijk, maar recycling blijft nuttig. Head-of-line blokkering verschuift naar frameniveau, dus ik blijf latency meten per Stroom. Als je meer in detail wilt vergelijken, vind je achtergrondinformatie op HTTP/2-multiplexing.

Onder HTTP/2 let ik vooral op het aantal actieve streams per verbinding. Te veel parallelle streams kunnen app-threads overbelasten. Ik vertraag dan de limieten of verhoog de server workers. Hier geldt hetzelfde: meten, aanpassen, opnieuw meten. Dit houdt de Reactietijden schaars en bewaard Bronnen.

TLS, sessiehervatting en HTTP/3/QUIC

TLS-handshakes zijn duur. Ik gebruik Sessie hervatten (tickets/ID's) en OCSP nieten zodat herverbindingen sneller verlopen als een verbinding toch verbroken wordt. Onder HTTP/3 neemt QUIC de transportlaag over: Hier is de QUIC idle timeout vergelijkbaar met Keep-Alive, maar dan op UDP-basis. Ook hier houd ik de vensters gematigd en meet ik retransmits, omdat pakketverlies een ander effect heeft dan bij TCP. Voor gemengde omgevingen (H1/H2/H3) kies ik gestandaardiseerde referentiewaarden en maak ik fijnafstellingen voor elk protocol.

Monitoring, statistieken en belastingstests

Ik vertrouw meer op meetgegevens dan op onderbuikgevoelens en begin met duidelijke KPI's. Belangrijk zijn: open sockets, FD-gebruik, nieuwe verbindingen/s, latencies (P50/P90/P99), foutpercentages en retransmits. Ik draai realistische belastingsprofielen: Opwarmen, plateau, ramp-down. Vervolgens vergelijk ik de curven voor en na het wijzigen van de time-out. Een blik op Serverwachtrij helpt om wachttijden duidelijk te interpreteren.

Ik documenteer elke aanpassing met een tijdstempel en meetwaarden. Hierdoor kan ik de geschiedenis bewaren en correlaties herkennen. Ik neem negatieve effecten serieus en draai ze snel terug. Kleine, begrijpelijke stappen besparen veel tijd. Wat uiteindelijk telt is een stabiele Latency en lage Foutenpercentage onder belasting.

Meetmethoden en -hulpmiddelen in de praktijk

  • Snelle tests: Ik gebruik tools zoals wrk, ab of vegeta om hergebruikquota (-H connection: keep-alive vs. close), verbindingen/s en latentiepercentielen te controleren.
  • Systeemoverzicht: ss/netstat toont statussen (ESTABLISHED, TIME_WAIT), lsof -p het verbruik van FD, dmesg/syslog geeft drops aan.
  • Web server statistieken: nginx stub_status/VTS en Apache mod_status geven active/idle/waiting en requests/s. Hieruit kan ik idle pieken of worker bottlenecks herkennen.
  • Sporen: Ik gebruik gedistribueerde tracing om te controleren of wachttijden optreden aan de netwerkgrens of in de app.

Stap voor stap configureren

Eerst bepaal ik het echte gebruikspatroon: hoeveel aanvragen per sessie, welke Intervallen tussen klikken, hoe groot zijn de reacties. Vervolgens stel ik een initieel profiel in: timeout 10 s, keepalive_requests 200, gematigd aantal werknemers. Vervolgens voer ik belastingstesten uit met representatieve gegevens. Ik evalueer het aantal nieuwe verbindingen per seconde en het FD-gebruik. Vervolgens pas ik de Waarden in stappen van 2-3 seconden.

Ik herhaal de cyclus totdat latencies stabiel blijven onder belasting en FD pieken de limiet niet bereiken. Bij zwaar verkeer verhoog ik de time-out alleen als ik duidelijk minder nieuwe verbindingen zie en de workers nog steeds vrij zijn. Bij laag gebruik verkort ik de time-out om idling te voorkomen. In speciale gevallen, zoals SSE, stel ik speciale serverblokken in met hogere limieten. Dit pad leidt tot een veerkrachtige Instelling zonder tariefkarton.

Kubernetes, containers en automatisch schalen

In containeromgevingen gebruik ik conntrack-limieten, pod FD-limieten en node-achterstanden. Ik zorg voor consistente idle timeouts tussen Ingress, service mesh/proxy en app. Voor auto-scaling let ik op AfvoertijdenWanneer pods beëindigd worden, moeten ze nieuwe verbindingen weigeren via „Connection: close“ en bestaande verbindingen netjes bedienen. Te lange "keep alive"-waarden verlengen de wachttijd onnodig, terwijl te korte waarden handshake stormen veroorzaken bij het uitschalen.

Graceful shutdown en rolling deployments

Ik ben ook van plan om uit te schakelen. Voor een uitrol verminder ik geleidelijk Keep-Alive of stuur ik gerichte Verbinding: sluiten op Reacties zodat clients geen nieuwe inactieve verbindingen openen. In nginx is een worker_shutdown_timeout voor lopende verzoeken. In Apache gebruik ik "graceful" mechanismen en houd ik MaxConnectionsPerChild/Worker in de gaten zodat er na verloop van tijd automatisch gerecycled wordt. Dit houdt implementaties soepel zonder hard-capping van open sockets.

OS afstellen: poorten, timeouts, kernelparameters

  • kortstondige poorten: Kies een breed bereik voor ip_local_port_range zodat kortstondige verbindingen niet op tekorten stuiten.
  • TIME_WAIT: Ik let op TW-pieken. Moderne stacks gaan hier goed mee om; ik vermijd onhandige tweaks (tw_recycle).
  • tcp_keepalive_time: Ik verwar het niet met HTTP Keep-Alive. Het is een kernelmechanisme voor het herkennen van dode peers - handig achter NAT, maar geen vervanging voor het HTTP idle window.
  • Achterstanden en buffers: dimensioneer somaxconn, tcp_max_syn_backlog en rmem/wmem op een verstandige manier om niet te smoren onder belasting.

Controlelijst voor probleemoplossing

  • Veel nieuwe verbindingen/ ondanks keep-alive: Time-out te kort of clients/LB eerder afgebroken.
  • Hoge stationaire cijfers en volledige FD's: Time-out te lang of werkerpools te groot voor het verkeerspatroon.
  • RST/Timeout-fout voor langere sessies: NAT/firewall idle te kort in het pad, asymmetrie tussen links.
  • Langstaartlatenties (P99): Controleer time-outs bij verzenden/lezen, trage clients of overvolle backlogs.
  • Backends overbelast ondanks lage randbelasting: Stroomopwaartse kooi ontbreekt of is te klein.

Praktijkprofielen en beginwaarden

  • API-first (korte oproepen): Keep-Alive 5-10 s, keepalive_requests 200-300, strakke header/leestimeouts.
  • E-commerce (gemengd): 8-12 s, 200-400, iets royaler voor productafbeeldingen en caching-hits.
  • Assets/CDN-achtig (veel kleine bestanden): 10-15 s, 300-500, sterke stroomopwaartse plassen en hoge FD-limieten.
  • Intranet/lage belasting: 5-8 s, 100-200, zodat stationair draaien niet overheerst.

Kort samengevat

Ik stel de HTTP keep-alive timeout zo in dat verbindingen worden hergebruikt zonder threads te blokkeren. In de praktijk leveren 5-15 seconden en 100-500 verzoeken per verbinding zeer goede resultaten. Ik coördineer timeouts van clients, loadbalancers en firewalls, scheid langlopende verbindingen zoals WebSockets en regel OS-limieten. Met schone monitoring, realistische belastingstests en kleine stappen bereik ik lage Latencies en hoge Doorvoer. Wie deze discipline aanhoudt, haalt meetbare prestaties uit bestaande hardware.

Huidige artikelen