{"id":21613,"date":"2026-09-21T08:33:31","date_gmt":"2026-09-21T06:33:31","guid":{"rendered":"https:\/\/webhosting.de\/nginx-upstream-keepalive-optimal-konfigurieren-reverse-proxy-netzwerk\/"},"modified":"2026-09-21T08:33:31","modified_gmt":"2026-09-21T06:33:31","slug":"optimal-konfiguration-af-nginx-upstream-keepalive-reverse-proxy-netvaerk","status":"publish","type":"post","link":"https:\/\/webhosting.de\/da\/nginx-upstream-keepalive-optimal-konfigurieren-reverse-proxy-netzwerk\/","title":{"rendered":"Optimal konfiguration af NGINX Upstream Keepalive for maksimal ydeevne som reverse proxy"},"content":{"rendered":"<p>Jeg konfigurerer NGINX Upstream Keepalive, s\u00e5 reverse-proxyen opretter f\u00e6rre forbindelser, giver lavere latenstider og p\u00e5lideligt afb\u00f8der belastningsspidser. I den forbindelse tilpasser jeg <strong>Poolst\u00f8rrelse<\/strong>, tidsgr\u00e6nser og headere m\u00e5lrettet, s\u00e5 forbindelser genbruges, og datastien forbliver slank.<\/p>\n\n<h2>Centrale punkter<\/h2>\n\n<ul>\n  <li><strong>HTTP\/1.1<\/strong> Tvinge og rense Connection-headere<\/li>\n  <li><strong>keepalive<\/strong> Dimensionere korrekt pr. medarbejder<\/li>\n  <li><strong>Timeouts<\/strong> tilpasse til backend-v\u00e6rdier<\/li>\n  <li><strong>Anmodninger\/Forbindelse<\/strong> begr\u00e6nse og genbruge<\/li>\n  <li><strong>Overv\u00e5gning<\/strong> for forbindelseshastighed og latenstid<\/li>\n<\/ul>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/nginx-serverkonfiguration-8234.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Hvorfor Upstream Keepalive reducerer forbindelsesomkostningerne drastisk<\/h2>\n\n<p>Uden genbrug opretter NGINX en ny backend-forbindelse for hver anmodning, hvilket medf\u00f8rer ekstra h\u00e5ndtryk, flere CPU-cyklusser og yderligere kernelressourcer; det er netop her, at <strong>Keepalive<\/strong> . Jeg lader NGINX cache allerede oprettede, midlertidigt inaktive sockets og bruge dem til efterf\u00f8lgende foresp\u00f8rgsler, hvilket m\u00e6rkbart reducerer forbindelsestiderne. Det s\u00e6nker antallet af forbindelser pr. sekund, mindsker spidsbelastninger i backloggen og begr\u00e6nser kontekstskift i operativsystemet. Is\u00e6r ved TLS til backend sparer jeg m\u00e6rkbart tid ved at genbruge sessioner. P\u00e5 den m\u00e5de forbliver svark\u00e6den stabil, selv ved h\u00f8j gennemstr\u00f8mning <strong>p\u00e5lidelig<\/strong> og reagerer smidigt.<\/p>\n\n<h2>Grundprincippet og keepalive-direktivet i upstream<\/h2>\n\n<p>Direktivet <strong>keepalive<\/strong> I upstream-blokken begr\u00e6nser man antallet af inaktive backend-forbindelser, der caches pr. worker. Denne begr\u00e6nsning g\u00e6lder ikke globalt, men udelukkende pr. worker-proces, og derfor holder jeg altid \u00f8je med antallet af workere. N\u00e5r puljen er fuld, lukker NGINX f\u00f8rst den forbindelse, der har v\u00e6ret ubenyttet l\u00e6ngst, s\u00e5 der bliver plads til nye sockets. For at kunne genbruge forbindelserne kr\u00e6ver proxysiden HTTP\/1.1 og en neutraliseret Connection-header. Uden disse foruds\u00e6tninger forbliver puljen tom, selvom jeg indstiller \u201ekeepalive\u201c i upstream, hvilket mange administratorer <strong>i starten<\/strong> overrasket.<\/p>\n\n<pre><code>upstream backend_pool {\n    server 192.168.1.10:8080;\n    server 192.168.1.11:8080;\n    server 192.168.1.12:8080;\n\n    keepalive 32; # inaktive forbindelser pr. worker\n    keepalive_requests 1000;   # genbrug efter N anmodninger\n    keepalive_timeout 60s;     # levetid for inaktive forbindelser\n}\n\nserver {\n    listen 80;\n    location \/ {\n proxy_pass http:\/\/backend_pool;\n proxy_http_version 1.1;\n proxy_set_header Connection \"\";\n    }\n}\n<\/code><\/pre>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/nginx_upstream_keepalive_3471.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Obligatoriske retningslinjer i Location-blokken: HTTP\/1.1 og kontrol af headere<\/h2>\n\n<p>Jeg tvinger NGINX til at bruge HTTP\/1.1 i proxystien, fordi Keepalive ikke fungerer korrekt med HTTP\/1.0, og forbindelserne afbrydes un\u00f8digt; direktivet <strong>proxy_http_version<\/strong> 1.1 er derfor obligatorisk. Derudover fjerner jeg Connection-headeren for almindelige anmodninger, s\u00e5 backendet ikke modtager en \u201eclose\u201c-instruktion. Ved opgraderinger som f.eks. WebSockets indstiller jeg m\u00e5lrettet \u201eConnection: Upgrade\u201c via map uden at p\u00e5virke den normale genbrug. P\u00e5 den m\u00e5de forbliver forbindelsespolitikken konsistent og adskilt fra klient-headere. Netop denne lille \u00e6ndring forhindrer mange sv\u00e6rt definerbare <strong>Fejlbilleder<\/strong>.<\/p>\n\n<pre><code>location \/ {\n    proxy_pass http:\/\/backend_pool;\n    proxy_http_version 1.1;\n    proxy_set_header Connection \"\";\n    proxy_set_header Upgrade $http_upgrade;\n    proxy_set_header Connection $connection_upgrade;\n}\n\nmap $http_upgrade $connection_upgrade {\n    default upgrade;\n    \"\" \"\";\n}\n<\/code><\/pre>\n\n<h2>Finjustering: V\u00e6lg de rigtige indstillinger for keepalive_requests og keepalive_timeout<\/h2>\n\n<p>Ved hj\u00e6lp af to justeringsskruer styrer jeg forbindelsernes levetid og fornyelse, s\u00e5 poolen forbliver opdateret, og der ikke er nogen forladte sockets, der forstyrrer; det er <strong>keepalive_requests<\/strong> og keepalive_timeout. Efter N anmodninger lukker NGINX forbindelsen m\u00e5lrettet og genopretter den om n\u00f8dvendigt, hvilket afb\u00f8der aldringseffekter i netv\u00e6rket. Jeg indstiller idle-timeout til en ret kort tid, som regel mellem 30 og 120 sekunder, s\u00e5 backend-serverne ikke afbryder forbindelsen f\u00f8r tid. Det er vigtigt at afstemme indstillingerne: NGINX-v\u00e6rdien m\u00e5 aldrig v\u00e6re l\u00e6ngere end app-serverens timeout, ellers vil der opst\u00e5 mange forbindelsesnulstillinger. Hvis du vil dykke dybere ned i emnet, finder du praktiske tip i artiklen <a href=\"https:\/\/webhosting.de\/da\/http-keepalive-timeout-konfiguration-af-serverens-ydeevne\/\">Keepalive-timeout<\/a>, der forklarer typiske v\u00e6rdier og sammenh\u00e6nge.<\/p>\n\n<p>For at give et hurtigt overblik viser jeg her de g\u00e6ngse startv\u00e6rdier og deres respektive form\u00e5l i en overskuelig <strong>Bord<\/strong>. Vejledende v\u00e6rdier fungerer som udgangspunkt og ender ofte lidt h\u00f8jere eller lavere efter overv\u00e5gning. En for kort tidsperiode medf\u00f8rer un\u00f8dvendige genopbygninger, mens en for lang tidsperiode fastholder gamle forbindelser. Antallet af anmodninger pr. forbindelse beskytter mod afvigelser, uden at puljen t\u00f8mmes. Med disse n\u00f8gletal opn\u00e5r jeg meget hurtigt velfungerende <strong>Standardindstillinger<\/strong>.<\/p>\n\n<table>\n  <thead>\n    <tr>\n      <th>Parametre<\/th>\n      <th>Form\u00e5l<\/th>\n      <th>referencev\u00e6rdi<\/th>\n      <th>Bem\u00e6rkning vedr\u00f8rende tuning<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>keepalive<\/td>\n      <td>St\u00f8rrelsen p\u00e5 idle-puljen pr. worker<\/td>\n      <td>32-64<\/td>\n      <td>Tilpas efter den samtidige belastning pr. worker<\/td>\n    <\/tr>\n    <tr>\n      <td>keepalive_requests<\/td>\n      <td>Maks. antal anmodninger pr. forbindelse<\/td>\n      <td>500\u20131000<\/td>\n      <td>Ved lange streams skal man indstille den lidt h\u00f8jere<\/td>\n    <\/tr>\n    <tr>\n      <td>keepalive_timeout<\/td>\n      <td>Maks. inaktivitetstid pr. forbindelse<\/td>\n      <td>60'erne<\/td>\n      <td>Kortere eller samme timeout for backend-inaktivitet<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<h2>Bestem poolst\u00f8rrelsen ud fra antallet af samtidige forbindelser<\/h2>\n\n<p>Jeg v\u00e6lger ikke poolst\u00f8rrelsen ud fra antallet af anmodninger pr. sekund, men ud fra <strong>Samtidighed<\/strong> pr. worker. F\u00f8rst beregner jeg det gennemsnitlige og det maksimale antal parallelle backend-anmodninger. Derefter deler jeg disse tal med antallet af NGINX-workere og afrunder op. Ved 200 samtidige foresp\u00f8rgsler og fire arbejdere ender jeg p\u00e5 ca. 50 pr. arbejdstager, hvilket betyder, at keepalive 64 passer som startv\u00e6rdi. P\u00e5 den m\u00e5de holder jeg soklerne tilg\u00e6ngelige uden un\u00f8digt mange \u00e5bne <strong>Forbindelser<\/strong> til at binde.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/nginx-reverse-proxy-setup-5038.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Bevidst udnytte de s\u00e6rlige egenskaber ved nyere NGINX-versioner<\/h2>\n\n<p>De nyeste versioner tillader ofte genbrug som standard, men s\u00e6tter ret konservative gr\u00e6nser; jeg indtaster v\u00e6rdierne alligevel <strong>eksplicit<\/strong> . Det sikrer reproducerbarhed, letter finjusteringen og forhindrer uventede problemer efter en opdatering. Via parameteren \u201elocal\u201c kan jeg valgfrit begr\u00e6nse genbrugen til en bestemt placering, hvis sikkerhedsprofiler eller header-politikker afviger. P\u00e5 den m\u00e5de forbliver adskillelsen klar, uden at fordelene ved genbrug p\u00e5 globalt plan g\u00e5r tabt. Med klare v\u00e6rdier dokumenterer jeg hensigter og sparer senere <strong>Analysetid<\/strong>.<\/p>\n\n<h2>Overv\u00e5gning og m\u00e5linger: Virker konfigurationen virkelig?<\/h2>\n\n<p>F\u00f8rst tjekker jeg antallet af nye backend-forbindelser pr. sekund; et markant fald viser, at foranstaltningerne virker <strong>Genbrug<\/strong>. Derefter overv\u00e5ger jeg upstream_connect_time, som ligger t\u00e6t p\u00e5 nul, n\u00e5r der er hits i poolen. Fejl i logfilerne, is\u00e6r forbindelsesafbrydelser, tyder p\u00e5 tidsgr\u00e6nser, der ligger bag backend-v\u00e6rdierne. Derudover korrelerer jeg backend-CPU og latenstider med andelen af genbrugte forbindelser. For en dybere forst\u00e5else af <a href=\"https:\/\/webhosting.de\/da\/http-forbindelse-genbrug-keepalive-optimering-serverperf-boost\/\">Genbrug af forbindelser<\/a> Eksempler, der viser virkningerne ved forskellige belastningsm\u00f8nstre, er til hj\u00e6lp.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/nginx_keepalive_1234.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Hurtigt afhj\u00e6lp typiske fejlkilder<\/h2>\n\n<p>Hvis der mangler HTTP\/1.1 til backend, vil forbindelserne v\u00e6re kortvarige, uanset hvor h\u00f8jt jeg <strong>keepalive<\/strong> s\u00e6tter. Hvis klienten sender \u201eConnection: close\u201c, og jeg videresender headeren ufiltreret, lukker backend\u2019en hver forbindelse umiddelbart efter svaret. Hvis idle-timeouts ikke stemmer overens, afbryder app-siden forbindelsen f\u00f8rst, og NGINX modtager en reset ved den n\u00e6ste anmodning. En overdimensioneret pool holder for mange sockets \u00e5bne og spilder hukommelse og porte. Jeg tjekker disse fire punkter ved hver analyse som <strong>F\u00f8rst<\/strong>, fordi de forklarer 90 % af alle problemer.<\/p>\n\n<h2>Praksisexempel: Standardkonfiguration til h\u00f8j gennemstr\u00f8mning<\/h2>\n\n<p>Med blot nogle f\u00e5 retningslinjer f\u00e5r jeg en st\u00e6rkt belastet proxy til at fungere hurtigt og p\u00e5lideligt og sikrer, at headere videresendes korrekt; f\u00f8lgende m\u00f8nster har vist sig at fungere godt og er let at <strong>Tilpas<\/strong>. Jeg indstiller keepalive til 64, begr\u00e6nser antallet af anmodninger pr. forbindelse til 1000 og holder en inaktivitetstid p\u00e5 60 sekunder. Derudover videresender jeg host- og forwarded-oplysninger korrekt, s\u00e5 backend-systemerne kan anvende logik og hastighedsbegr\u00e6nsning. Denne kombination sk\u00e5ner CPU\u2019en, forkorter svartiderne og h\u00e5ndterer belastningsspidser mere roligt. P\u00e5 netop denne m\u00e5de opn\u00e5r jeg en godt forudsigelig <strong>Ydelse<\/strong>.<\/p>\n\n<pre><code>upstream app_backend {\n    server 10.0.1.10:3000 max_fails=2 fail_timeout=30s;\n    server 10.0.1.11:3000 max_fails=2 fail_timeout=30s;\n\n    keepalive 64;\n    keepalive_requests 1000;\n    keepalive_timeout 60s;\n}\n\nserver {\n    listen 80;\n    server_name example.com;\n\n    location \/ {\n proxy_pass http:\/\/app_backend;\n proxy_http_version 1.1;\n proxy_set_header Connection \"\";\n proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n    }\n}\n<\/code><\/pre>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/nginx-keepalive-setup-3294.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Hostingmilj\u00f8er og driftsm\u00e6ssige aspekter, der virkelig t\u00e6ller<\/h2>\n\n<p>Jeg placerer ofte NGINX foran PHP-FPM-, Node.js- eller Java-tjenester og s\u00f8rger for, at netv\u00e6rksforsinkelserne holdes p\u00e5 et lavt niveau, og at backend-timeouts er ensartede; det giver <strong>Planl\u00e6gbarhed<\/strong>. En solid kernel-netv\u00e6rkskonfiguration med passende socket-gr\u00e6nser forhindrer, at mange \u00e5bne forbindelser kolliderer. J\u00e6vn CPU-fordeling og hurtige lagringsveje hj\u00e6lper backend-serverne med at opretholde korte svartider. Derudover s\u00f8rger jeg for versionerede konfigurationer, s\u00e5 \u00e6ndringer forbliver sporbare. Med denne disciplin forbliver systemet stabilt selv under trafikspidser <strong>reagerbar<\/strong>.<\/p>\n\n<h2>Bedste praksis for l\u00f8bende drift<\/h2>\n\n<p>Jeg starter med keepalive 32\u201364, 500\u20131000 anmodninger pr. forbindelse og 60 sekunders inaktivitetstid, m\u00e5ler derefter systematisk og justerer v\u00e6rdierne; det giver hurtige <strong>succeser<\/strong>. Hver \u00e6ndring ledsager jeg med m\u00e5linger af forbindelseshastighed, latenstid og fejlm\u00f8nstre, indtil kurverne udviser en mere stabil udvikling. Jeg tilpasser poolens st\u00f8rrelse efter antallet af samtidige foresp\u00f8rgsler, ikke efter den r\u00e5 gennemstr\u00f8mning pr. sekund. Timeouts m\u00e5 aldrig v\u00e6re l\u00e6ngere end de tilsvarende i backend-stakken, ellers risikerer man sporadiske resets. Hvis du \u00f8nsker at finjustere yderligere, finder du vejledning til finjustering under <a href=\"https:\/\/webhosting.de\/da\/optimering-af-nginx-keepalive-anmodninger-ydeevneoptimering-af-webserveren\/\">Optimering af keepalive-anmodninger<\/a>, hvilket g\u00f8r genanvendelsen let at h\u00e5ndtere.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/nginx-server-einstellung-7845.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Justering af proxy-timeouts og TCP-keepalive<\/h2>\n\n<p>Ud over de rene keepalive-parametre tilpasser jeg transporttidsgr\u00e6nserne n\u00f8jagtigt. Kombinationen af <strong>proxy_connect_timeout<\/strong>, <strong>proxy_send_timeout<\/strong> og <strong>proxy_read_timeout<\/strong> bestemmer, hvor t\u00e5lmodig NGINX er ved opbygning, afsendelse og modtagelse. Jeg indstiller disse v\u00e6rdier aldrig h\u00f8jere end de tilsvarende v\u00e6rdier i backend, men lidt lavere, s\u00e5 fejl bliver synlige tidligt og ikke eskalerer p\u00e5 app-siden. Derudover aktiverer jeg <strong>proxy_socket_keepalive<\/strong>, s\u00e5 operativsystemet med j\u00e6vne mellemrum sender livstegn via inaktive sockets og registrerer halv\u00e5bne forbindelser. Dette forhindrer, at d\u00f8de forbindelser forbliver i puljen og for\u00e5rsager forsinkelsestop ved den n\u00e6ste anmodning.<\/p>\n\n<pre><code>server {\n    listen 80;\n\n    location \/ {\n proxy_pass http:\/\/backend_pool;\n\n proxy_connect_timeout 3s;   # hurtigt fejl, hvis forbindelse ikke er mulig\n proxy_send_timeout    30s;  # Skrivning til backend\n proxy_read_timeout    30s;  # Svar fra backend\n proxy_socket_keepalive on;  # Aktiver OS-TCP-keepalive\n    }\n}\n<\/code><\/pre>\n\n<p>For langvarige streams (f.eks. SSE eller WebSockets) \u00f8ger jeg udelukkende read-timeout, mens Connect forbliver lukket. P\u00e5 den m\u00e5de reagerer jeg hurtigt p\u00e5 defekte m\u00e5l, men lader legitime, lange svar k\u00f8re uforstyrret igennem.<\/p>\n\n<h2>Ressourceplanl\u00e6gning: worker_connections, FD\u2019er og midlertidige porte<\/h2>\n\n<p>En ren keepalive-pulje nytter ikke noget, hvis filbeskrivelsesgr\u00e6nser eller portomr\u00e5der udt\u00f8mmes. Derfor planl\u00e6gger jeg <strong>arbejdstager_forbindelser<\/strong> og <strong>worker_rlimit_nofile<\/strong> med en vis margen. Groft regnet: \u00c5bne FD\u2019er \u2248 (samtidige klientforbindelser + samtidige backend-forbindelser + poolede inaktive sockets) pr. worker. Hvis jeg bruger flere upstreams med puljer, bliver behovet mangedoblet. Ligeledes er jeg opm\u00e6rksom p\u00e5 systemets ephemeral-port-omr\u00e5de, da NGINX fungerer som TCP-klient i retning af backend og akkumulerer TIME_WAIT-tilstande.<\/p>\n\n<pre><code>worker_processes auto;\nworker_rlimit_nofile 131072;\n\nevents {\n    worker_connections 8192;\n}\n<\/code><\/pre>\n\n<pre><code># Linux-eksempler (sysctl):\nnet.core.somaxconn = 4096\nnet.ipv4.ip_local_port_range = 10240 65535\nnet.ipv4.tcp_fin_timeout = 15\n<\/code><\/pre>\n\n<p>Jeg v\u00e6lger en konservativ tilgang: Jeg afbryder ikke TIME_WAIT for aggressivt, men s\u00e6nker i stedet forbindelsesfrekvensen via Keepalive. P\u00e5 den m\u00e5de forbliver kerneparametrene ukritiske, og adf\u00e6rden forbliver forudsigelig.<\/p>\n\n<h2>Upstream-zoner, balanceringsstrategi og DNS-rotation<\/h2>\n\n<p>Hvis der er flere arbejdere, deler jeg balancertilstanden via en <strong>zone<\/strong>, s\u00e5 nedbrud og belastning forbliver ensartede. Keepalive-sockets forbliver ganske vist fortsat pr. worker, men fordelingen bliver mere j\u00e6vn. Ved dynamiske backends, der flytter via DNS, indstiller jeg \u201e<strong>l\u00f8se<\/strong>\u201c i serverlinjerne og definer en <strong>resolver<\/strong>. Vigtigt: N\u00e5r IP-adresserne skifter, genbruger puljen ikke straks alle gamle sockets; jeg mener derfor, at <em>keepalive_requests<\/em> og tidsfrister inden for realistiske rammer, s\u00e5 fornyelsen hurtigt sl\u00e5r igennem.<\/p>\n\n<pre><code>upstream backend_pool {\n    zone backend_zone 128k;  # deler balancer-tilstand\n    least_conn; # retf\u00e6rdig fordeling ved lange anmodninger\n\n server app-1.internal:8080 resolve;\n    server app-2.internal:8080 resolve;\n\n keepalive 64;\n    keepalive_requests 1000;\n    keepalive_timeout 60s;\n}\n\nresolver 10.0.0.2 valid=30s;\nresolver_timeout 5s;\n\nproxy_next_upstream error timeout http_502 http_504;\nproxy_next_upstream_tries 2;  # f\u00e5, m\u00e5lrettede gentagelser\n<\/code><\/pre>\n\n<p>For sessioner, der er bundet til en bestemt backend-node (f.eks. sticky-state), kombinerer jeg genbrug med <em>ip_hash<\/em> eller en ekstern sessionsmekanisme. Dette forhindrer, at forbindelsespooling forstyrrer sessionskonsistensen.<\/p>\n\n<h2>TLS til backend: SNI, genbrug af sessioner og krypteringsalgoritmer<\/h2>\n\n<p>Jo mere TLS der bruges i backend-stien, desto mere v\u00e6rdifuld er Keepalive. Jeg aktiverer SNI, angiver det forventede navn og s\u00f8rger for, at TLS-sessionen genbruges. Det reducerer h\u00e5ndtryksomkostningerne og udj\u00e6vner spidsbelastninger i latenstiden. Jeg v\u00e6lger krypteringssuiter og protokoller med omhu, uden at udelukke \u00e6ldre backends. Ved certifikatvalidering (valgfrit) skal tillidsk\u00e6den v\u00e6re fuldst\u00e6ndig, ellers falder forbindelserne sporadisk ud.<\/p>\n\n<pre><code>upstream https_backend {\n    server backend.example.local:443;\n    keepalive 32;\n}\n\nserver {\n    listen 443 ssl;\n\n location \/ {\n proxy_pass https:\/\/https_backend;\n proxy_http_version 1.1;\n proxy_set_header Connection \"\";\n\n        proxy_ssl_server_name on;\n proxy_ssl_name backend.example.local;\n proxy_ssl_session_reuse on;\n proxy_ssl_protocols TLSv1.2 TLSv1.3;\n        proxy_ssl_ciphers HIGH:!aNULL:!MD5;\n # optional: proxy_ssl_verify on;\n # optional: proxy_ssl_trusted_certificate \/etc\/nginx\/ca.pem;\n    }\n}\n<\/code><\/pre>\n\n<p>N\u00e5r jeg selv har kontrol over backend-siden, aktiverer jeg session-tickets eller -caches der og bruger m\u00e5linger til at kontrollere, om genoptagelsesprocenten stiger. I kombination med Keepalive opn\u00e5r jeg p\u00e5 den m\u00e5de vedvarende lave forbindelses- og handshake-tider.<\/p>\n\n<h2>S\u00e6rlige tilf\u00e6lde: gRPC, WebSockets og forbindelsesbaseret autentificering<\/h2>\n\n<p>Med <strong>gRPC<\/strong> fungerer NGINX upstream via HTTP\/2. Her giver f\u00e5 langvarige forbindelser med mange streams ofte de bedste resultater; puljen forbliver lille, men stabil. For <strong>WebSockets<\/strong> Jeg indstiller lange l\u00e6setimeouts og beholder header-logikken fra map-l\u00f8sningen, s\u00e5 opgraderingsforbindelser ikke ved en fejltagelse lukkes. <strong>NTLM<\/strong> eller andre forbindelsesbaserede autentificeringer kr\u00e6ver connection pinning; jeg opdeler s\u00e5danne stier i egne lokationer og begr\u00e6nser pooling eller genbrug d\u00e9r, s\u00e5 sikkerhedshandshakes ikke blandes sammen mellem klienter.<\/p>\n\n<pre><code># gRPC-eksempel\nlocation \/grpc.Service\/ {\n    grpc_pass grpc:\/\/backend_pool;\n    grpc_read_timeout 300s;  Tillad # lange streams\n}\n<\/code><\/pre>\n\n<p>Det er afg\u00f8rende at fastl\u00e6gge en konsekvent forbindelsespolitik for hver rute og kun anvende keepalive i stort omfang d\u00e9r, hvor det ikke er semantisk kritisk.<\/p>\n\n<h2>M\u00e5lbarhed i praksis: Access-logfiler med upstream-timinger<\/h2>\n\n<p>Jeg udvider Access-loggen med upstream-metrikker. P\u00e5 den m\u00e5de kan jeg med et blik se, om et svar kom fra en socket i poolen (meget kort forbindelsestid), og hvor ofte der opst\u00e5r backend-fejl. Derudover logger jeg forbindelsesnummeret og antallet af anmodninger via den aktuelle klientforbindelse for at finde sammenh\u00e6nge.<\/p>\n\n<pre><code>log_format upstream_timing '$remote_addr - $host \"$request\" '\n 'up=$upstream_addr '\n 'sc=$status usc=$upstream_status '\n                           'cc=$connection cr=$connection_requests '\n 'tc=$upstream_connect_time '\n 'th=$upstream_header_time '\n 'tr=$upstream_response_time';\n\naccess_log \/var\/log\/nginx\/access_upstream.log upstream_timing;\n<\/code><\/pre>\n\n<p>Derudover bruger jeg status-endpunkter og operativsystemets socket-statistikker. En sund tilstand viser: faldende forbindelseshastighed til backend, kortere upstream_connect_time, stabile svartider og n\u00e6sten ingen forbindelsesnulstillinger. Afvigelser tyder n\u00e6sten altid p\u00e5 uafstemte tidsgr\u00e6nser eller for sm\u00e5\/for store puljer.<\/p>\n\n<h2>Udrulningsstrategi og risikominimering<\/h2>\n\n<p>Jeg g\u00e5r frem trin for trin: sm\u00e5 skridt, m\u00e5ling, justering. F\u00f8rst aktiverer jeg Keepalive i moderat omfang, derefter justerer jeg timeouts og antal anmodninger pr. forbindelse. \u00c6ndringerne implementerer jeg ved at genindl\u00e6se siden uden at afbryde aktive forbindelser. P\u00e5 den m\u00e5de forbliver risikoen lav, og effekterne kan tydeligt tilskrives de enkelte \u00e6ndringer.<\/p>\n\n<pre><code># Valider \u00e6ndringer og indl\u00e6s dem uden nedetid\nnginx -t &amp;&amp; nginx -s reload\n<\/code><\/pre>\n\n<p>N\u00e5r jeg k\u00f8rer flere upstreams, finjusterer jeg dem \u00e9n efter \u00e9n, begyndende med den mest kritiske vej. Hvert trin f\u00e5r et observationsvindue, s\u00e5 m\u00f8nstre i m\u00e5lingerne tydeligt kan fremst\u00e5. F\u00f8rst derefter skalerer jeg v\u00e6rdierne op eller ned.<\/p>\n\n<h2>Kort oversigt over din reverse proxy<\/h2>\n\n<p>Jeg bruger HTTP\/1.1, t\u00f8mmer Connection-headeren og v\u00e6lger poolst\u00f8rrelsen ud fra antallet af samtidige anmodninger, ikke ud fra RPS; det underst\u00f8tter <strong>Str\u00f8m<\/strong>. Med keepalive_requests og keepalive_timeout holder jeg forbindelserne aktive og undg\u00e5r uventede problemer som f\u00f8lge af for\u00e6ldede sockets. Overv\u00e5gningen viser, om upstream_connect_time n\u00e6rmer sig nul, og om forbindelseshastigheden til backend falder. Ved fejl tjekker jeg f\u00f8rst protokolversion, header-videresendelse, tidsgr\u00e6nser og poolst\u00f8rrelse. S\u00e5dan holder du din NGINX-proxy k\u00f8rende under h\u00f8j belastning <strong>lydh\u00f8r<\/strong> og forudsigelig.<\/p>","protected":false},"excerpt":{"rendered":"<p>L\u00e6r, hvordan du konfigurerer NGINX Upstream Keepalive optimalt i nginx-upstream-blokken for at g\u00f8re din reverse proxy betydeligt mere effektiv.<\/p>","protected":false},"author":1,"featured_media":21606,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[834],"tags":[],"class_list":["post-21613","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-plesk-webserver-plesk-administration-anleitungen"],"acf":[],"_wp_attached_file":null,"_wp_attachment_metadata":null,"litespeed-optimize-size":null,"litespeed-optimize-set":null,"_elementor_source_image_hash":null,"_wp_attachment_image_alt":null,"stockpack_author_name":null,"stockpack_author_url":null,"stockpack_provider":null,"stockpack_image_url":null,"stockpack_license":null,"stockpack_license_url":null,"stockpack_modification":null,"color":null,"original_id":null,"original_url":null,"original_link":null,"unsplash_location":null,"unsplash_sponsor":null,"unsplash_exif":null,"unsplash_attachment_metadata":null,"_elementor_is_screenshot":null,"surfer_file_name":null,"surfer_file_original_url":null,"envato_tk_source_kit":null,"envato_tk_source_index":null,"envato_tk_manifest":null,"envato_tk_folder_name":null,"envato_tk_builder":null,"envato_elements_download_event":null,"_menu_item_type":null,"_menu_item_menu_item_parent":null,"_menu_item_object_id":null,"_menu_item_object":null,"_menu_item_target":null,"_menu_item_classes":null,"_menu_item_xfn":null,"_menu_item_url":null,"_trp_menu_languages":null,"rank_math_primary_category":null,"rank_math_title":null,"inline_featured_image":null,"_yoast_wpseo_primary_category":null,"rank_math_schema_blogposting":null,"rank_math_schema_videoobject":null,"_oembed_049c719bc4a9f89deaead66a7da9fddc":null,"_oembed_time_049c719bc4a9f89deaead66a7da9fddc":null,"_yoast_wpseo_focuskw":null,"_yoast_wpseo_linkdex":null,"_oembed_27e3473bf8bec795fbeb3a9d38489348":null,"_oembed_c3b0f6959478faf92a1f343d8f96b19e":null,"_trp_translated_slug_en_us":null,"_wp_desired_post_slug":null,"_yoast_wpseo_title":null,"tldname":null,"tldpreis":null,"tldrubrik":null,"tldpolicylink":null,"tldsize":null,"tldregistrierungsdauer":null,"tldtransfer":null,"tldwhoisprivacy":null,"tldregistrarchange":null,"tldregistrantchange":null,"tldwhoisupdate":null,"tldnameserverupdate":null,"tlddeletesofort":null,"tlddeleteexpire":null,"tldumlaute":null,"tldrestore":null,"tldsubcategory":null,"tldbildname":null,"tldbildurl":null,"tldclean":null,"tldcategory":null,"tldpolicy":null,"tldbesonderheiten":null,"tld_bedeutung":null,"_oembed_d167040d816d8f94c072940c8009f5f8":null,"_oembed_b0a0fa59ef14f8870da2c63f2027d064":null,"_oembed_4792fa4dfb2a8f09ab950a73b7f313ba":null,"_oembed_33ceb1fe54a8ab775d9410abf699878d":null,"_oembed_fd7014d14d919b45ec004937c0db9335":null,"_oembed_21a029d076783ec3e8042698c351bd7e":null,"_oembed_be5ea8a0c7b18e658f08cc571a909452":null,"_oembed_a9ca7a298b19f9b48ec5914e010294d2":null,"_oembed_f8db6b27d08a2bb1f920e7647808899a":null,"_oembed_168ebde5096e77d8a89326519af9e022":null,"_oembed_cdb76f1b345b42743edfe25481b6f98f":null,"_oembed_87b0613611ae54e86e8864265404b0a1":null,"_oembed_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_oembed_time_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_tldname":null,"_tldclean":null,"_tldpreis":null,"_tldcategory":null,"_tldsubcategory":null,"_tldpolicy":null,"_tldpolicylink":null,"_tldsize":null,"_tldregistrierungsdauer":null,"_tldtransfer":null,"_tldwhoisprivacy":null,"_tldregistrarchange":null,"_tldregistrantchange":null,"_tldwhoisupdate":null,"_tldnameserverupdate":null,"_tlddeletesofort":null,"_tlddeleteexpire":null,"_tldumlaute":null,"_tldrestore":null,"_tldbildname":null,"_tldbildurl":null,"_tld_bedeutung":null,"_tldbesonderheiten":null,"_oembed_ad96e4112edb9f8ffa35731d4098bc6b":null,"_oembed_8357e2b8a2575c74ed5978f262a10126":null,"_oembed_3d5fea5103dd0d22ec5d6a33eff7f863":null,"_eael_widget_elements":null,"_oembed_0d8a206f09633e3d62b95a15a4dd0487":null,"_oembed_time_0d8a206f09633e3d62b95a15a4dd0487":null,"_aioseo_description":null,"_eb_attr":null,"_eb_data_table":null,"_oembed_819a879e7da16dd629cfd15a97334c8a":null,"_oembed_time_819a879e7da16dd629cfd15a97334c8a":null,"_acf_changed":null,"_wpcode_auto_insert":null,"_edit_last":null,"_edit_lock":null,"_oembed_e7b913c6c84084ed9702cb4feb012ddd":null,"_oembed_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_time_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_03514b67990db061d7c4672de26dc514":null,"_oembed_time_03514b67990db061d7c4672de26dc514":null,"rank_math_news_sitemap_robots":null,"rank_math_robots":null,"_eael_post_view_count":"107","_trp_automatically_translated_slug_ru_ru":null,"_trp_automatically_translated_slug_et":null,"_trp_automatically_translated_slug_lv":null,"_trp_automatically_translated_slug_fr_fr":null,"_trp_automatically_translated_slug_en_us":null,"_wp_old_slug":null,"_trp_automatically_translated_slug_da_dk":null,"_trp_automatically_translated_slug_pl_pl":null,"_trp_automatically_translated_slug_es_es":null,"_trp_automatically_translated_slug_hu_hu":null,"_trp_automatically_translated_slug_fi":null,"_trp_automatically_translated_slug_ja":null,"_trp_automatically_translated_slug_lt_lt":null,"_elementor_edit_mode":null,"_elementor_template_type":null,"_elementor_version":null,"_elementor_pro_version":null,"_wp_page_template":null,"_elementor_page_settings":null,"_elementor_data":null,"_elementor_css":null,"_elementor_conditions":null,"_happyaddons_elements_cache":null,"_oembed_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_time_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_time_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_59808117857ddf57e478a31d79f76e4d":null,"_oembed_time_59808117857ddf57e478a31d79f76e4d":null,"_oembed_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_time_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_81002f7ee3604f645db4ebcfd1912acf":null,"_oembed_time_81002f7ee3604f645db4ebcfd1912acf":null,"_elementor_screenshot":null,"_oembed_7ea3429961cf98fa85da9747683af827":null,"_oembed_time_7ea3429961cf98fa85da9747683af827":null,"_elementor_controls_usage":null,"_elementor_page_assets":null,"_elementor_screenshot_failed":null,"theplus_transient_widgets":null,"_eael_custom_js":null,"_wp_old_date":null,"_trp_automatically_translated_slug_it_it":null,"_trp_automatically_translated_slug_pt_pt":null,"_trp_automatically_translated_slug_zh_cn":null,"_trp_automatically_translated_slug_nl_nl":null,"_trp_automatically_translated_slug_pt_br":null,"_trp_automatically_translated_slug_sv_se":null,"rank_math_analytic_object_id":null,"rank_math_internal_links_processed":"1","_trp_automatically_translated_slug_ro_ro":null,"_trp_automatically_translated_slug_sk_sk":null,"_trp_automatically_translated_slug_bg_bg":null,"_trp_automatically_translated_slug_sl_si":null,"litespeed_vpi_list":null,"litespeed_vpi_list_mobile":null,"rank_math_seo_score":null,"rank_math_contentai_score":null,"ilj_limitincominglinks":null,"ilj_maxincominglinks":null,"ilj_limitoutgoinglinks":null,"ilj_maxoutgoinglinks":null,"ilj_limitlinksperparagraph":null,"ilj_linksperparagraph":null,"ilj_blacklistdefinition":null,"ilj_linkdefinition":null,"_eb_reusable_block_ids":null,"rank_math_focus_keyword":"NGINX Upstream","rank_math_og_content_image":null,"_yoast_wpseo_metadesc":null,"_yoast_wpseo_content_score":null,"_yoast_wpseo_focuskeywords":null,"_yoast_wpseo_keywordsynonyms":null,"_yoast_wpseo_estimated-reading-time-minutes":null,"rank_math_description":null,"surfer_last_post_update":null,"surfer_last_post_update_direction":null,"surfer_keywords":null,"surfer_location":null,"surfer_draft_id":null,"surfer_permalink_hash":null,"surfer_scrape_ready":null,"_thumbnail_id":"21606","footnotes":null,"_links":{"self":[{"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/posts\/21613","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/comments?post=21613"}],"version-history":[{"count":0,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/posts\/21613\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/media\/21606"}],"wp:attachment":[{"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/media?parent=21613"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/categories?post=21613"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/tags?post=21613"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}