{"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":"configuracion-optima-de-keepalive-en-upstream-de-nginx-proxy-inverso-y-red","status":"publish","type":"post","link":"https:\/\/webhosting.de\/es\/nginx-upstream-keepalive-optimal-konfigurieren-reverse-proxy-netzwerk\/","title":{"rendered":"Configurar de forma \u00f3ptima el \u00abKeepalive\u00bb de NGINX Upstream para obtener el m\u00e1ximo rendimiento como proxy inverso"},"content":{"rendered":"<p>Configurar\u00e9 el \u00abUpstream Keepalive\u00bb de NGINX para que el proxy inverso establezca menos conexiones, ofrezca menores latencias y absorba de forma fiable los picos de carga. Para ello, ajustar\u00e9 <strong>Tama\u00f1o de la piscina<\/strong>, los l\u00edmites de tiempo y los encabezados de forma espec\u00edfica, para que se reutilicen las conexiones y la ruta de datos se mantenga optimizada.<\/p>\n\n<h2>Puntos centrales<\/h2>\n\n<ul>\n  <li><strong>HTTP\/1.1<\/strong> Forzar y depurar los encabezados de conexi\u00f3n<\/li>\n  <li><strong>keepalive<\/strong> dimensionar correctamente por trabajador<\/li>\n  <li><strong>Tiempos muertos<\/strong> adaptar a los valores del backend<\/li>\n  <li><strong>Solicitudes\/Conexi\u00f3n<\/strong> reducir y reciclar<\/li>\n  <li><strong>Monitoreo<\/strong> en cuanto a velocidad de conexi\u00f3n y latencia<\/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>Por qu\u00e9 Upstream Keepalive reduce dr\u00e1sticamente el esfuerzo de establecimiento de conexiones<\/h2>\n\n<p>Sin reutilizaci\u00f3n, NGINX abre una nueva conexi\u00f3n con el backend por cada solicitud, lo que conlleva m\u00e1s intercambios de datos, un mayor consumo de ciclos de CPU y un uso adicional de recursos del n\u00facleo; es precisamente aqu\u00ed donde entra en juego <strong>Keepalive<\/strong> . Hago que NGINX almacene en cach\u00e9 los sockets ya establecidos que se encuentran inactivos en ese momento y los utilice para las solicitudes posteriores, lo que reduce de forma apreciable los tiempos de conexi\u00f3n. Esto disminuye la tasa de conexiones por segundo, reduce los picos de backlog y frena los cambios de contexto en el sistema operativo. Especialmente con TLS hacia el backend, ahorro tiempo de forma notable gracias a la reutilizaci\u00f3n de sesiones. De este modo, la cadena de respuestas se mantiene estable incluso con un alto rendimiento <strong>fiable<\/strong> y responde con fluidez.<\/p>\n\n<h2>Principio b\u00e1sico y la directiva \u00abkeepalive\u00bb en el upstream<\/h2>\n\n<p>La directiva <strong>keepalive<\/strong> En el bloque \u201eupstream\u201c se limita el n\u00famero de conexiones de backend inactivas almacenadas temporalmente por cada trabajador. Este l\u00edmite no es global, sino que se aplica estrictamente por cada proceso de trabajador, por lo que siempre estoy pendiente del n\u00famero de trabajadores. Cuando el grupo est\u00e1 lleno, NGINX cierra primero la conexi\u00f3n que lleva m\u00e1s tiempo sin utilizarse, para que haya espacio para nuevos sockets. Para la reutilizaci\u00f3n, el lado del proxy necesita HTTP\/1.1 y un encabezado \u00abConnection\u00bb neutralizado. Sin estos requisitos, el grupo permanece vac\u00edo, aunque configure \u00abkeepalive\u00bb en el upstream, algo que muchos administradores <strong>al principio<\/strong> sorprendido.<\/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; # conexiones inactivas por trabajador\n    keepalive_requests 1000;   # reciclaje tras N solicitudes\n    keepalive_timeout 60s;     # tiempo de vida en inactividad\n}\n\nservidor {\n    escuchar 80;\n    ubicaci\u00f3n \/ {\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>Directivas obligatorias en el bloque \u00abLocation\u00bb: HTTP\/1.1 y control de encabezados<\/h2>\n\n<p>En la ruta del proxy, obligo a NGINX a utilizar HTTP\/1.1, ya que Keepalive no funciona correctamente con HTTP\/1.0 y las conexiones se cierran innecesariamente; la directiva <strong>proxy_http_version<\/strong> Por lo tanto, 1.1 es obligatorio. Adem\u00e1s, elimino el encabezado \u201eConnection\u201c de las solicitudes normales, para que el backend no reciba una instrucci\u00f3n \u201eclose\u201c. Para actualizaciones como WebSockets, establezco de forma espec\u00edfica \u00abConnection: Upgrade\u00bb mediante map, sin afectar a la reutilizaci\u00f3n habitual. De este modo, la pol\u00edtica de conexi\u00f3n se mantiene coherente y desacoplada de los encabezados del cliente. Es precisamente este peque\u00f1o cambio el que evita muchos problemas dif\u00edciles de detectar <strong>Im\u00e1genes de errores<\/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>Ajuste preciso: seleccionar correctamente los valores de \u00abkeepalive_requests\u00bb y \u00abkeepalive_timeout\u00bb<\/h2>\n\n<p>Con dos tornillos de ajuste controlo la duraci\u00f3n y la renovaci\u00f3n de las conexiones, para que la piscina se mantenga limpia y no haya sockets abandonados que molesten; estos son <strong>keepalive_requests<\/strong> y keepalive_timeout. Tras N solicitudes, NGINX cierra la conexi\u00f3n de forma selectiva y la restablece si es necesario, lo que mitiga los efectos del envejecimiento de la red. Suelo fijar el tiempo de espera de inactividad (Idle-Timeout) en un valor bastante ajustado, normalmente entre 30 y 120 segundos, para que los servidores backend no se desconecten antes de tiempo. Es importante el equilibrio: el valor de NGINX nunca debe superar el tiempo de espera de los servidores de aplicaciones, ya que, de lo contrario, se acumular\u00edan los reinicios de conexi\u00f3n. Quien desee profundizar en los aspectos t\u00e9cnicos, encontrar\u00e1 consejos pr\u00e1cticos en el art\u00edculo <a href=\"https:\/\/webhosting.de\/es\/http-keepalive-timeout-server-performance-configuration\/\">Tiempo de espera de keepalive<\/a>, que explica los valores t\u00edpicos y las interacciones.<\/p>\n\n<p>Para facilitar la orientaci\u00f3n, muestro los valores iniciales habituales y su finalidad respectiva en una tabla clara <strong>Cuadro<\/strong>. Los valores de referencia sirven como punto de partida y, tras el seguimiento, suelen acabar siendo algo m\u00e1s altos o m\u00e1s bajos. Un periodo demasiado corto genera nuevas conexiones innecesarias, mientras que uno demasiado largo mantiene conexiones antiguas. El n\u00famero de solicitudes por conexi\u00f3n me protege de los valores at\u00edpicos, sin vaciar el grupo. Con estos datos clave, consigo soluciones que funcionan muy r\u00e1pidamente. <strong>Por defecto<\/strong>.<\/p>\n\n<table>\n  <thead>\n    <tr>\n      <th>Par\u00e1metros<\/th>\n      <th>Prop\u00f3sito<\/th>\n      <th>valor indicativo<\/th>\n      <th>Nota sobre el tuning<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>keepalive<\/td>\n      <td>Tama\u00f1o del grupo de procesos inactivos por trabajador<\/td>\n      <td>32-64<\/td>\n      <td>Ajustar seg\u00fan la carga simult\u00e1nea por trabajador<\/td>\n    <\/tr>\n    <tr>\n      <td>keepalive_requests<\/td>\n      <td>Solicitudes m\u00e1ximas por conexi\u00f3n<\/td>\n      <td>500\u20131000<\/td>\n      <td>En el caso de transmisiones largas, f\u00edjalo un poco m\u00e1s alto<\/td>\n    <\/tr>\n    <tr>\n      <td>tiempo de espera de keepalive<\/td>\n      <td>Tiempo m\u00e1ximo de inactividad por conexi\u00f3n<\/td>\n      <td>los a\u00f1os 60<\/td>\n      <td>Tiempo de espera de inactividad del backend m\u00e1s corto o igual<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<h2>Determinar el tama\u00f1o del grupo en funci\u00f3n de las conexiones simult\u00e1neas<\/h2>\n\n<p>No elijo el tama\u00f1o del pool en funci\u00f3n de las solicitudes por segundo, sino en funci\u00f3n de <strong>Concurrencia<\/strong> por trabajador. En primer lugar, calculo el n\u00famero medio y m\u00e1ximo de solicitudes paralelas al backend. A continuaci\u00f3n, divido estas cifras entre el n\u00famero de trabajadores de NGINX y redondeo al alza. Para 200 solicitudes simult\u00e1neas con cuatro workers, obtengo un resultado de unas 50 por worker, por lo que un valor inicial de keepalive de 64 resulta adecuado. De esta forma, mantengo los sockets disponibles sin abrir un n\u00famero innecesario de <strong>Conexiones<\/strong> para atar.<\/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>Aprovechar deliberadamente las caracter\u00edsticas especiales de las versiones m\u00e1s recientes de NGINX<\/h2>\n\n<p>Las versiones actuales suelen permitir la reutilizaci\u00f3n de forma predeterminada, aunque establecen l\u00edmites bastante conservadores; aun as\u00ed, voy a introducir los valores <strong>expl\u00edcito<\/strong> . Esto garantiza la reproducibilidad, facilita el ajuste y evita sorpresas tras una actualizaci\u00f3n. Mediante el par\u00e1metro \u201elocal\u201c, puedo limitar opcionalmente la reutilizaci\u00f3n a una ubicaci\u00f3n concreta si los perfiles de seguridad o las pol\u00edticas de encabezados difieren. De este modo, la separaci\u00f3n se mantiene clara, sin perder las ventajas de la reutilizaci\u00f3n a nivel global. Con valores claros, documento mis intenciones y me ahorro trabajo m\u00e1s adelante <strong>Tiempo de an\u00e1lisis<\/strong>.<\/p>\n\n<h2>Supervisi\u00f3n y m\u00e9tricas: \u00bffunciona realmente la configuraci\u00f3n?<\/h2>\n\n<p>En primer lugar, compruebo el n\u00famero de nuevas conexiones al backend por segundo; una disminuci\u00f3n significativa indica que las medidas est\u00e1n surtiendo efecto <strong>Reutilice<\/strong>. A continuaci\u00f3n, observo el \u00abupstream_connect_time\u00bb, que se sit\u00faa cerca de cero cuando hay coincidencias en el pool. Los errores en los registros, especialmente los restablecimientos de conexi\u00f3n, apuntan a l\u00edmites de tiempo que est\u00e1n por detr\u00e1s de los valores del backend. Adem\u00e1s, correlaciono la CPU del backend y las latencias con el porcentaje de conexiones reutilizadas. Para comprender mejor la <a href=\"https:\/\/webhosting.de\/es\/conexion-http-reutilizacion-keepalive-optimizacion-serverperf-boost\/\">Reutilizaci\u00f3n de conexiones<\/a> Son de ayuda los ejemplos que muestran los efectos en distintos patrones de carga.<\/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>Eliminar r\u00e1pidamente las fuentes t\u00edpicas de errores<\/h2>\n\n<p>Si no hay HTTP\/1.1 hacia el backend, las conexiones duran muy poco, por mucho que yo <strong>keepalive<\/strong> establezco. Si el cliente env\u00eda \u201eConnection: close\u201c y yo paso el encabezado sin filtrar, el backend libera cada conexi\u00f3n inmediatamente despu\u00e9s de la respuesta. Si los tiempos de espera de inactividad no coinciden, el lado de la aplicaci\u00f3n cierra la conexi\u00f3n primero y NGINX recibe un reinicio en la siguiente solicitud. Un pool sobredimensionado mantiene abiertos demasiados sockets y desperdicia memoria y puertos. Compruebo estos cuatro puntos en cada an\u00e1lisis como <strong>Primero<\/strong>, porque explican el 90 % de todos los problemas.<\/p>\n\n<h2>Ejemplo pr\u00e1ctico: configuraci\u00f3n de referencia para un alto rendimiento<\/h2>\n\n<p>Con unas pocas instrucciones, consigo que un proxy muy sobrecargado funcione de forma r\u00e1pida y fiable y garantizo un reenv\u00edo correcto de los encabezados; el siguiente modelo ha demostrado su eficacia y es f\u00e1cil de <strong>personalizar<\/strong>. Establezco el keepalive en 64, limito las solicitudes por conexi\u00f3n a 1000 y mantengo un tiempo de inactividad de 60 segundos. Adem\u00e1s, transmito correctamente la informaci\u00f3n del host y de reenv\u00edo para que los backends puedan aplicar la l\u00f3gica y la limitaci\u00f3n de tasa. Esta combinaci\u00f3n reduce la carga de la CPU, acorta los tiempos de respuesta y permite gestionar los picos de carga con mayor tranquilidad. As\u00ed es precisamente como consigo una <strong>Actuaci\u00f3n<\/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>Entornos de alojamiento y aspectos operativos que realmente importan<\/h2>\n\n<p>A menudo utilizo NGINX delante de PHP-FPM, Node.js o servicios Java, y me aseguro de que las latencias de red sean m\u00ednimas y de que los tiempos de espera del backend sean constantes; esto proporciona <strong>Planificabilidad<\/strong>. Una configuraci\u00f3n de red del kernel s\u00f3lida, con l\u00edmites de sockets adecuados, evita que se produzcan colisiones entre numerosas conexiones abiertas. Una asignaci\u00f3n uniforme de la CPU y rutas de almacenamiento r\u00e1pidas ayudan a los backends a mantener tiempos de respuesta cortos. Adem\u00e1s, me encargo de que las configuraciones est\u00e9n versionadas, para que los cambios sean trazables. Con esta disciplina, el sistema se mantiene estable incluso en picos de tr\u00e1fico <strong>reaccionable<\/strong>.<\/p>\n\n<h2>Buenas pr\u00e1cticas para las operaciones en curso<\/h2>\n\n<p>Empiezo con un keepalive de 32-64, 500-1000 solicitudes por conexi\u00f3n y un tiempo de inactividad de 60 segundos; despu\u00e9s realizo mediciones sistem\u00e1ticas y ajusto los valores; esto permite una r\u00e1pida <strong>\u00e9xitos<\/strong>. Acompa\u00f1o cada cambio con m\u00e9tricas sobre la tasa de conexi\u00f3n, la latencia y los patrones de error, hasta que las curvas se estabilicen. Ajusto el tama\u00f1o del pool en funci\u00f3n de las solicitudes simult\u00e1neas, no del rendimiento bruto por segundo. Los tiempos de espera nunca deben ser m\u00e1s largos que los de sus hom\u00f3logos en la pila de backend; de lo contrario, se corre el riesgo de que se produzcan reinicios espor\u00e1dicos. Quien desee ajustar la velocidad con mayor precisi\u00f3n encontrar\u00e1 indicaciones sobre el ajuste fino en <a href=\"https:\/\/webhosting.de\/es\/optimizar-las-solicitudes-keepalive-de-nginx-ajuste-del-rendimiento-del-servidor-web\/\">Optimizar las solicitudes Keepalive<\/a>, lo que hace que el reciclaje sea f\u00e1cil de gestionar.<\/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>Sincronizaci\u00f3n de los tiempos de espera del proxy y del \u00abkeepalive\u00bb de TCP<\/h2>\n\n<p>Adem\u00e1s de los par\u00e1metros puros de Keepalive, ajusto con precisi\u00f3n los l\u00edmites de tiempo de transporte. La tr\u00edada formada por <strong>proxy_connect_timeout<\/strong>, <strong>proxy_send_timeout<\/strong> y <strong>proxy_read_timeout<\/strong> Determina el nivel de paciencia de NGINX a la hora de establecer conexiones, enviar y recibir datos. Nunca establezco estos valores por encima de los correspondientes en el backend, sino ligeramente por debajo, para que los errores se detecten pronto y no se agraven en el lado de la aplicaci\u00f3n. Adem\u00e1s, activo <strong>proxy_socket_keepalive<\/strong>, para que el sistema operativo env\u00ede se\u00f1ales de vida a intervalos regulares a trav\u00e9s de los sockets inactivos y detecte las conexiones semiabiertas. Esto evita que las conexiones inactivas permanezcan en el grupo y provoquen picos de latencia en la siguiente solicitud.<\/p>\n\n<pre><code>server {\n    listen 80;\n\n    location \/ {\n proxy_pass http:\/\/backend_pool;\n\n proxy_connect_timeout 3s;   #: fallar r\u00e1pidamente si no es posible establecer la conexi\u00f3n\n proxy_send_timeout    30s;  # Escritura en el backend\n proxy_read_timeout    30s;  # Respuestas del backend\n proxy_socket_keepalive on;  # Activar el keepalive TCP del sistema operativo\n    }\n}\n<\/code><\/pre>\n\n<p>En el caso de flujos de datos de larga duraci\u00f3n (por ejemplo, SSE o WebSockets), solo aumento el tiempo de espera de lectura, mientras que el de conexi\u00f3n se mantiene igual. De esta forma, reacciono r\u00e1pidamente ante destinos defectuosos, pero dejo que las respuestas leg\u00edtimas y largas se procesen sin interrupciones.<\/p>\n\n<h2>Planificaci\u00f3n de recursos: worker_connections, FD y puertos ef\u00edmeros<\/h2>\n\n<p>Un grupo de keepalive limpio no sirve de nada si se agotan los l\u00edmites de descriptores de archivo o los rangos de puertos. Por eso tengo pensado <strong>conexiones_trabajadores<\/strong> y <strong>worker_rlimit_nofile<\/strong> con margen. A grandes rasgos, calculo lo siguiente: FD abiertos \u2248 (conexiones simult\u00e1neas de clientes + conexiones simult\u00e1neas de backend + sockets inactivos agrupados en un pool) por trabajador. Si utilizo varios upstreams con pools, la demanda se multiplica. Asimismo, presto atenci\u00f3n al rango de puertos ef\u00edmeros del sistema, ya que NGINX act\u00faa como cliente TCP hacia el backend y acumula estados TIME_WAIT.<\/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>Ejemplos de Linux para # (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>Adopto un enfoque conservador: no elimino el TIME_WAIT de forma agresiva, sino que reduzco la frecuencia de conexi\u00f3n mediante Keepalive. De este modo, los par\u00e1metros del n\u00facleo no se ven afectados de forma cr\u00edtica y el comportamiento sigue siendo predecible.<\/p>\n\n<h2>Zonas de origen, estrategia de equilibrio de carga y rotaci\u00f3n de DNS<\/h2>\n\n<p>Si hay varios trabajadores, comparto el estado del equilibrador a trav\u00e9s de una <strong>zona<\/strong>, para que las ca\u00eddas y las cargas se mantengan constantes. Aunque las conexiones Keepalive siguen asign\u00e1ndose por trabajador, la distribuci\u00f3n es m\u00e1s uniforme. En el caso de backends din\u00e1micos que cambian de ubicaci\u00f3n a trav\u00e9s del DNS, configuro \u201e<strong>resolver<\/strong>\u201c en las l\u00edneas del servidor y define un <strong>resolver<\/strong>. Importante: cuando las direcciones IP rotan, el grupo no recicla inmediatamente todos los sockets antiguos; por lo tanto, considero que <em>keepalive_requests<\/em> y plazos realistas, para que la renovaci\u00f3n surta efecto r\u00e1pidamente.<\/p>\n\n<pre><code>upstream backend_pool {\n    zone backend_zone 128k;  # comparte el estado del equilibrador\n    least_conn; # distribuci\u00f3n equitativa en solicitudes largas\n\n server app-1.internal:8080 resolve;\n    servidor app-2.internal:8080 resolver;\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;  #: pocas repeticiones selectivas\n<\/code><\/pre>\n\n<p>Para las sesiones vinculadas a un nodo de backend concreto (por ejemplo, \u00absticky-state\u00bb), combino la reutilizaci\u00f3n con <em>ip_hash<\/em> o un mecanismo de sesi\u00f3n externo. Esto evita que el agrupamiento de conexiones afecte a la coherencia de la sesi\u00f3n.<\/p>\n\n<h2>TLS hacia el backend: SNI, reutilizaci\u00f3n de sesiones y algoritmos de cifrado<\/h2>\n\n<p>Cuanto m\u00e1s se utilice TLS en la ruta de backend, m\u00e1s valioso resulta Keepalive. Activo SNI, defino el nombre esperado y me aseguro de que se reutilice la sesi\u00f3n TLS. Esto reduce los costes del handshake y suaviza los picos de latencia. Selecciono las suites de cifrado y los protocolos de forma restrictiva, sin excluir los backends m\u00e1s antiguos. En la verificaci\u00f3n de certificados (opcional), la cadena de confianza debe estar completa; de lo contrario, las conexiones se interrumpir\u00e1n espor\u00e1dicamente.<\/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 # opcional: proxy_ssl_verify on;\n # opcional: proxy_ssl_trusted_certificate \/etc\/nginx\/ca.pem;\n    }\n}\n<\/code><\/pre>\n\n<p>Si controlo yo mismo el backend, activo all\u00ed los tickets de sesi\u00f3n o las cach\u00e9s y compruebo, mediante m\u00e9tricas, si aumentan las tasas de reanudaci\u00f3n. En combinaci\u00f3n con Keepalive, consigo as\u00ed tiempos de conexi\u00f3n y de handshake bajos de forma permanente.<\/p>\n\n<h2>Casos especiales: gRPC, WebSockets y autenticaci\u00f3n vinculada a la conexi\u00f3n<\/h2>\n\n<p>En <strong>gRPC<\/strong> NGINX funciona en la capa superior a trav\u00e9s de HTTP\/2. En este caso, unas pocas conexiones de larga duraci\u00f3n con muchos flujos suelen ofrecer los mejores resultados; el grupo de conexiones se mantiene peque\u00f1o, pero estable. Para <strong>WebSockets<\/strong> Establezco tiempos de espera de lectura largos y mantengo la l\u00f3gica de los encabezados de la soluci\u00f3n \u00abmap\u00bb, para que las conexiones de actualizaci\u00f3n no se cierren por error. <strong>NTLM<\/strong> o bien otras autenticaciones vinculadas a la conexi\u00f3n requieren \u00abconnection pinning\u00bb; separo esas rutas en ubicaciones independientes y reduzco all\u00ed el uso de pools o la reutilizaci\u00f3n, para que los handshakes de seguridad no se mezclen entre clientes.<\/p>\n\n<pre><code>Ejemplo de gRPC con #\nlocation \/grpc.Service\/ {\n    grpc_pass grpc:\/\/backend_pool;\n    grpc_read_timeout 300s;  Permitir flujos largos con #\n}\n<\/code><\/pre>\n\n<p>Es fundamental establecer una pol\u00edtica de conexi\u00f3n coherente para cada ruta y utilizar Keepalive de forma generalizada \u00fanicamente en aquellos casos en los que no sea cr\u00edtico desde el punto de vista sem\u00e1ntico.<\/p>\n\n<h2>La medibilidad en la pr\u00e1ctica: registros de acceso con tiempos de transmisi\u00f3n ascendente<\/h2>\n\n<p>Ampl\u00edo el registro de Access con m\u00e9tricas de upstream. As\u00ed puedo ver de un vistazo si una respuesta proced\u00eda de un socket agrupado (tiempo de conexi\u00f3n muy corto) y con qu\u00e9 frecuencia se producen errores en el backend. Adem\u00e1s, registro el n\u00famero de conexi\u00f3n y el n\u00famero de solicitudes realizadas a trav\u00e9s de la conexi\u00f3n actual del cliente para detectar correlaciones.<\/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>Adem\u00e1s, utilizo los puntos finales de estado y las estad\u00edsticas de sockets del sistema operativo. Un estado \u00f3ptimo se caracteriza por: una tasa de conexi\u00f3n al backend en descenso, un tiempo de conexi\u00f3n ascendente (upstream_connect_time) m\u00e1s corto, tiempos de respuesta estables y apenas reinicios de conexi\u00f3n. Las desviaciones suelen indicar casi siempre que los l\u00edmites de tiempo no est\u00e1n bien ajustados o que los grupos de conexiones son demasiado peque\u00f1os o demasiado grandes.<\/p>\n\n<h2>Estrategia de implantaci\u00f3n y ajuste con bajo riesgo<\/h2>\n\n<p>Sigo un proceso iterativo: peque\u00f1os pasos, medir y ajustar. Primero activo el keepalive de forma moderada y, a continuaci\u00f3n, ajusto los tiempos de espera y el n\u00famero de solicitudes por conexi\u00f3n. Aplico los cambios actualizando la p\u00e1gina, sin desconectar las conexiones activas. De esta forma, el riesgo es m\u00ednimo y los efectos se pueden atribuir con claridad.<\/p>\n\n<pre><code>#: validar los cambios y cargarlos sin tiempo de inactividad\nnginx -t &amp;&amp; nginx -s reload\n<\/code><\/pre>\n\n<p>Cuando gestiono varios flujos ascendentes, los ajusto uno tras otro, empezando por la ruta m\u00e1s cr\u00edtica. A cada etapa le asigno un periodo de observaci\u00f3n para que se puedan identificar claramente los patrones en las m\u00e9tricas. Solo entonces aumento o reduzco los valores.<\/p>\n\n<h2>Resumen conciso sobre tu proxy inverso<\/h2>\n\n<p>Apuesto por HTTP\/1.1, dejo vac\u00edo el encabezado \u00abConnection\u00bb y elijo el tama\u00f1o del grupo en funci\u00f3n de las solicitudes simult\u00e1neas, no de las RPS; esto contribuye a la <strong>Actuaci\u00f3n<\/strong>. Con \u00abkeepalive_requests\u00bb y \u00abkeepalive_timeout\u00bb mantengo las conexiones activas y evito sorpresas debidas a sockets obsoletos. La supervisi\u00f3n muestra si \u00abupstream_connect_time\u00bb tiende a cero y si la tasa de conexi\u00f3n con el backend disminuye. En caso de errores, compruebo primero la versi\u00f3n del protocolo, la transmisi\u00f3n de encabezados, los tiempos de espera y el tama\u00f1o del grupo. As\u00ed se mantiene tu proxy NGINX bajo una carga elevada <strong>receptivo<\/strong> y previsible.<\/p>","protected":false},"excerpt":{"rendered":"<p>Aprende a configurar de forma \u00f3ptima el \u00abupstream keepalive\u00bb de NGINX en el bloque \u00abupstream\u00bb de NGINX para mejorar notablemente el rendimiento de tu proxy inverso.<\/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":"110","_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\/es\/wp-json\/wp\/v2\/posts\/21613","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/webhosting.de\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/webhosting.de\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/webhosting.de\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/webhosting.de\/es\/wp-json\/wp\/v2\/comments?post=21613"}],"version-history":[{"count":0,"href":"https:\/\/webhosting.de\/es\/wp-json\/wp\/v2\/posts\/21613\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/webhosting.de\/es\/wp-json\/wp\/v2\/media\/21606"}],"wp:attachment":[{"href":"https:\/\/webhosting.de\/es\/wp-json\/wp\/v2\/media?parent=21613"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/webhosting.de\/es\/wp-json\/wp\/v2\/categories?post=21613"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/webhosting.de\/es\/wp-json\/wp\/v2\/tags?post=21613"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}