Volver al blog

Proxying HTTP, balanceo de carga, almacenamiento en búfer y almacenamiento en caché de Nginx: una descripción general

Proxying HTTP, balanceo de carga, almacenamiento en búfer y almacenamiento en caché de Nginx: una descripción general
Introducción

Nginx es un servidor web de alto rendimiento que también se utiliza como proxy inverso, proxy de correo, equilibrador de carga y caché HTTP. Nginx es gratuito y de código abierto, lo que permite a cualquiera descargarlo y usarlo en su entorno de servidor.

Es posible que ya haya utilizado Nginx para servir sitios web. En este tutorial, discutiremos las otras capacidades de Nginx. La función de proxy HTTP de Nginx le permite pasar solicitudes a servidores HTTP backend para su procesamiento. Con esta función, puede configurar múltiples servidores backend. Le permite escalar su infraestructura según sea necesario para manejar picos en las solicitudes de los clientes.

A medida que avancemos con el tutorial, aprenderá a escalar su infraestructura utilizando las propiedades de equilibrio de carga de Nginx, el almacenamiento en búfer, y el almacenamiento en caché de respuestas para mejorar el rendimiento de su servidor, así como para garantizar una mejor experiencia para los clientes. ¡Comencemos!

Antes que nada, para comenzar con Nginx, eche un vistazo a nuestro tutorial sobre cómo instalar Nginx en su servidor Ubuntu.

Información general sobre el uso de proxies

Si sus conocimientos sobre servidores web se limitan a procesar solicitudes de sitios web y servir páginas web, es posible que se pregunte por qué necesitamos actuar como proxy para las solicitudes. A continuación explicaremos las razones detrás de esto.

Una razón para redirigir solicitudes a otros servidores desde Nginx es admitir la escalabilidad de su infraestructura. Nginx, por defecto, maneja muchas conexiones de forma concurrente. Esto lo hace perfecto para ser el primer punto de contacto para los clientes. Y luego puede pasar las solicitudes a varios servidores backend para que se encarguen del procesamiento real de las solicitudes de los clientes. Esto es lo que distribuye la carga. Por lo tanto, garantiza que pueda escalar su infraestructura tanto como sea posible. También le permite dar de baja otros servidores para mantenimiento mientras otros continúan atendiendo solicitudes.

La segunda razón por la que podría querer redirigir solicitudes a otros servidores es cuando utiliza servidores de aplicaciones que no son adecuados para manejar solicitudes directamente de los clientes en entornos de producción en vivo. Varios frameworks, incluidos los servidores web, no son adecuados para un alto rendimiento como Nginx. Permitir que Nginx sea el punto de entrada y redirija las solicitudes a estos servidores de bajo rendimiento puede garantizar que sus usuarios tengan una mejor experiencia. Además, puede garantizar una mayor seguridad para su aplicación.

El proceso de proxying de solicitudes en Nginx implica manipular una solicitud del servidor Nginx y pasarla a otros servidores backend para el procesamiento real. Una vez que los otros servidores backend han procesado la solicitud, devuelven el resultado a Nginx. Luego, este envía el resultado como respuesta al cliente. El cliente en este caso es un navegador web o incluso una aplicación web móvil. Los otros servidores backend pueden ser servidores locales que no son accesibles públicamente en Internet, servidores remotos o incluso otros servidores virtuales dentro de las configuraciones de bloques de servidor de Nginx. Estos otros servidores a los que Nginx redirige las solicitudes se denominan servidores upstream.

Nginx puede redirigir solicitudes a servidores que se comunican utilizando varios protocolos, incluidos HTTP(S), Memcached, SCGI, FastCGI, y uWSGI. Para cada tipo de protocolo, existen conjuntos de directivas. Nuestro enfoque para este tutorial es el protocolo HTTP. Nginx analiza las solicitudes y los componentes del mensaje en un formato que el servidor upstream puede interpretar y procesar.

Análisis de un Proxy Pass HTTP básico

El tipo más simple de proxy implica pasar una solicitud a un solo servidor que se comunica a través de HTTP. Este tipo de proxy generalmente se conoce como "proxy pass" y se maneja mediante la directiva proxy_pass, acertadamente nombrada, dentro de los archivos de configuración de Nginx.

La directiva proxy_pass aparece dentro de los bloques location. También se encuentra dentro de los bloques de un contexto de ubicación y en contextos limit_except. Cuando una solicitud coincide con una ubicación que contiene una directiva proxy_pass, la solicitud se dirige a la URL que especifica la directiva. A continuación se muestra un ejemplo de un fragmento de configuración:

proxy_pass_conf

En el ejemplo anterior, las solicitudes al puerto 80 irían a localhost:3000:

nginx default page

La captura de pantalla anterior muestra la página predeterminada de Nginx cuando intenta acceder a localhost. Después de reiniciar el servidor Nginx con la directiva proxy_pass en vigor, todas las solicitudes irán al puerto 3000. Una aplicación de demostración se está ejecutando en el puerto 3000, lo cual puede ver en la imagen a continuación, y puede acceder directamente desde localhost sin especificar el puerto:

localhost after applying proy pass

En el siguiente ejemplo, no se ha especificado ningún URI al final del servidor en la definición de proxy_pass. Para las definiciones que se ajustan a este patrón, el URI que solicita el cliente se pasará al servidor ascendente tal como está.

Por ejemplo, cuando este bloque maneja una solicitud para /match/url/here, el URI de la solicitud irá al servidor de example.com como http://example.com/match/url/here.

A continuación se muestra un ejemplo de un fragmento de configuración alternativo:

Como puede ver en el fragmento anterior, hemos definido un segmento de URI al final del servidor proxy como new/url/prefix. Cuando define un URI en la definición de proxy_pass, la parte de la solicitud que coincide con la definición de location se reemplaza por este URI al ir al servidor ascendente para su procesamiento.

Por ejemplo, una solicitud para /match/url/here en el servidor Nginx pasa al servidor ascendente como http://example.com/new/url/here. El /match/url se reemplaza por /new/url. Tenga en cuenta este punto.

En algunos casos, la transferencia de URI como la anterior no es posible. En tales casos, Nginx ignora el URI al final de la definición de proxy_pass. En última instancia, se pasa al servidor ascendente el URI original del cliente o el URI que modifican otras directivas.

Un ejemplo es cuando las expresiones regulares coinciden con la ubicación (location). Es posible que Nginx no pueda determinar qué parte del URI coincidió con la expresión. Por lo tanto, envía el URI de solicitud original del cliente. Esto provoca la reescritura y el manejo del URI del cliente en el mismo bloque. En tal caso, se pasa el URI reescrito.

¿Cómo procesa Nginx las cabeceras?

Las cabeceras son cruciales para la forma en que un servidor procesa una solicitud. Algunas cabeceras pueden incluir información de autenticación. Por lo tanto, debemos entender cómo el proxy de Nginx procesará las cabeceras. La solicitud de proxy de Nginx al servidor ascendente se verá diferente de la que provino directamente del cliente. Algunas de las diferencias son el resultado de las cabeceras que acompañan a la solicitud de proxy.

Durante el proxy de una solicitud, Nginx realizará ajustes en las cabeceras de solicitud que recibe del cliente. Algunos de esos ajustes incluyen:

  • Eliminar todas las cabeceras vacías. Las cabeceras vacías solo sobrecargan la solicitud, por lo que no tiene sentido pasarlas al servidor ascendente.

  • Cualquier cabecera que contenga guiones bajos se considera inválida por defecto, por lo que se elimina de la solicitud. Si desea cambiar este comportamiento y permitir que Nginx interprete las cabeceras con guiones bajos como válidas, puede establecer la directiva underscores_in_headers en “on”. Si no lo hace, dichas cabeceras del cliente nunca llegarán al servidor ascendente.

  • La cabecera “Host” se reescribe con el valor especificado por la variable $proxy_host. Esta es la dirección IP o el nombre y el número de puerto del servidor ascendente, según lo especificado por la directiva proxy_pass.

  • El valor de la cabecera “Connection” cambia a “close”. La cabecera de conexión contiene información sobre una conexión particular establecida entre dos partes. Cuando Nginx establece su valor en close, indica al servidor ascendente que la conexión se cerrará una vez que se haya respondido a la solicitud original, por lo que no debe esperar que sea una conexión persistente.

Aquí hay algunos puntos que podemos notar de los ajustes de las cabeceras de solicitud de proxy descritos anteriormente:

  • Si no desea que se pase una cabecera al servidor ascendente, establecerla como una cadena vacía la eliminará por completo de la solicitud.

  • Si la aplicación en su servidor ascendente va a procesar cabeceras no estándar, asegúrese de que las cabeceras no tengan un guion bajo. Opcionalmente, puede establecer la directiva underscores_in_headers en “on” en su configuración (válida ya sea en el contexto de la declaración del servidor predeterminado para la combinación de dirección IP/puerto o en el contexto HTTP). Al hacerlo, se asegurará de que las cabeceras no se marquen como no válidas y, por lo tanto, se pasen realmente al servidor ascendente.

  • La cabecera “Host” es bastante importante en la mayoría de las situaciones de proxy. De forma predeterminada, se establece en el valor de $proxy_host, una variable que contiene el nombre de dominio o la dirección IP y el puerto recuperados de la especificación proxy_pass. Esta dirección se selecciona de forma predeterminada y se extrae directamente de la información de conexión. Es la única dirección para la que Nginx tiene la garantía de que el servidor ascendente responderá.

A continuación se muestran los valores más comunes para la cabecera “Host”:

  • $host – una variable que se establece en orden de preferencia según el nombre de host de la propia línea de solicitud, la cabecera “Host” de la solicitud del cliente o el nombre del servidor que coincide con la solicitud.

  • $http_host – una variable que establece la cabecera “Host” con el valor de la cabecera “Host” de la solicitud del cliente. Las cabeceras de la solicitud del cliente siempre están disponibles para Nginx como variables. Estas variables comienzan con el prefijo $http_, seguido del nombre de la cabecera en minúsculas. Aunque la variable $http_host funcionará bien en la mayoría de los casos, cuando la solicitud del cliente carece de una cabecera “Host” válida, puede provocar que la transferencia falle.

  • $proxy_host – una variable que establece la cabecera “Host” con el nombre de dominio o la combinación de dirección IP y puerto recuperados de la especificación de proxy_pass. Este es el comportamiento predeterminado, desde el punto de vista de Nginx, y por lo tanto se considera seguro. Sin embargo, puede que no sea lo que el servidor necesita para procesar la solicitud correctamente.

La mayoría de las configuraciones implicarán establecer la cabecera “Host” en la variable $host. Es muy flexible y proporcionará cabeceras completadas con precisión al servidor ascendente.

Establecer y modificar cabeceras

La directiva proxy_set_header nos permite establecer o modificar cabeceras para conexiones proxy. En la cabecera “Host” analizada anteriormente, podemos hacer lo siguiente para modificar y añadir cabeceras adicionales comunes con las solicitudes proxy:

En el fragmento de configuración anterior, establecemos la cabecera “Host” en la variable $host que contiene información sobre el host original solicitado. Establecemos la cabecera X-Forwarded-Proto con información sobre el esquema de la solicitud original del cliente (esta puede ser una solicitud HTTP o HTTPS).

Pasamos la dirección IP real del cliente a X-Real-IP. Esto permite que el servidor ascendente tome decisiones adecuadas o almacene registros basados en el origen de la IP del cliente. La cabecera X-Forwarded-For contiene una lista de todas las direcciones IP que pertenecen a los servidores a través de los cuales se ha redirigido al cliente antes de llegar a este punto. En el fragmento de código anterior, la establecemos en la variable $proxy_add_x_forwarded_for. Esta variable tomará el valor de la cabecera X-Forwarded-For original obtenida del cliente y añadirá la dirección IP del servidor proxy Nginx al final.

Si desea que se haga referencia a las directivas proxy_set_header en más de una ubicación, puede moverlas al contexto server o http. Considere el siguiente fragmento de configuración:

Definición de un contexto upstream para balancear la carga de conexiones con proxy

Hasta este punto, ya comprende cómo realizar un proxy http simple a un único servidor upstream de backend. Afortunadamente, con Nginx, puede escalar dicha configuración definiendo grupos de servidores backend a los que pasar las solicitudes para su procesamiento.

Nginx proporciona una directiva llamada upstream que se utiliza para definir un grupo de servidores. Dentro de la configuración de la directiva, solo debe especificar servidores que sean capaces de manejar la solicitud de un cliente. Nginx como servidor proxy permite escalar la infraestructura con el mínimo esfuerzo. La directiva upstream debe especificarse dentro del contexto http de su configuración de Nginx.

Aquí hay un ejemplo que muestra la directiva upstream:

En el fragmento de código de configuración anterior, hemos definido un contexto upstream llamado several_backend_hosts. El nombre del contexto definido ahora está disponible dentro de los proxy passes. Se puede utilizar como si fuera un dominio normal, como se muestra en el ejemplo. Dentro del bloque server, pasamos todas las solicitudes realizadas a example.com/proxy-me/… al grupo que definimos usando la directiva upstream, en este caso, several_backend_hosts. Se selecciona un host dentro del grupo para manejar las solicitudes entrantes aplicando un algoritmo configurable. Por defecto, la selección sigue un proceso round-robin (circular): cada solicitud se enruta a un host diferente a su vez.

Cómo cambiar el algoritmo de balanceo de upstream

Como se destacó anteriormente, el proceso de selección sigue un proceso round-robin. En esta sección, veremos cómo podemos modificar el algoritmo de balanceo utilizado por el grupo (pool) de upstream. Para modificar el algoritmo, se incluyen otras directivas o flags dentro del contexto upstream como se define a continuación:

  • (round-robin) – si no se especifica ninguna otra directiva de balanceo de upstream, por defecto, a cada servidor definido en el contexto upstream se le pasan las solicitudes de forma secuencial a su vez.

  • least_conn – esta directiva indica al upstream que seleccione el servidor backend con el menor número de conexiones activas. Esto es aplicable en situaciones donde las conexiones a un servidor backend pueden persistir durante un tiempo.

  • hash – esta directiva es común para el proxying de memcached. Las conexiones se pasan a los servidores backend según el valor de una clave hash proporcionada aleatoriamente. El valor de la clave hash puede ser variables, texto o una combinación de ambos. hash resulta ser el único método de balanceo que requiere la entrada de los usuarios para actuar como la clave que se utilizará para el hash.

  • ip_hash – esta directiva indica al upstream que distribuya las solicitudes a diferentes servidores según la dirección IP del cliente. Los primeros tres octetos de la dirección IP son la clave para determinar qué servidor debe procesar una solicitud. Una ventaja de esta directiva es que los clientes tienden a recibir el mismo servidor cada vez, lo que garantiza la consistencia de la sesión.

Aquí hay un ejemplo de cómo podemos agregar la directiva del algoritmo de balanceo al contexto upstream:

En el fragmento anterior, Nginx seleccionará cualquiera de los servidores con la menor cantidad de conexiones para procesar una solicitud entrante. La directiva ip_hash sigue la misma sintaxis. Para la directiva hash, debe proporcionar una clave de su elección para realizar el hash, aquí tiene un ejemplo:

El hash utilizado aquí será el resultado de la dirección IP y el puerto del cliente. El parámetro opcional consistent implementa el algoritmo de hash consistente ketama. Esto garantiza un impacto mínimo en su caché en caso de que cambie sus servidores upstream.

Cómo especificar el peso del servidor para el balanceo

Por defecto, al declarar servidores backend, cada servidor tiene el mismo peso. Se asume que cada servidor tiene los recursos y capacidades para manejar la misma cantidad de carga, por supuesto, esto teniendo en cuenta cualquier algoritmo de balanceo que especifique en el contexto upstream. Para cambiar este comportamiento predeterminado, puede establecer un peso alternativo para cada servidor durante la declaración. Consideremos un ejemplo:

En este ejemplo, host1.example.com recibirá el doble de tráfico que los otros dos servidores. El peso de cada servidor es uno por defecto.

Liberar servidores backend con búferes

Al configurar el proxy en la configuración de su servidor, es posible que le preocupe el impacto en el rendimiento de agregar más servidores al proceso. Afortunadamente, Nginx viene con funciones de almacenamiento en búfer y caché que pueden ayudar a mitigar estos problemas de rendimiento.

La velocidad de dos conexiones diferentes seguramente afectará la experiencia del cliente al realizar el proxy a otro servidor:

  • La primera conexión es desde el cliente al proxy Nginx.

  • La segunda conexión es desde el proxy Nginx al servidor upstream backend.

Nginx puede ajustar su comportamiento para ayudar a optimizar cualquiera de las conexiones según sea necesario.

Si eliminamos los búferes, la transmisión de datos desde el backend upstream al cliente comienza de inmediato en el proxy Nginx. Si sabe que sus clientes son rápidos, puede desactivar por completo el almacenamiento en búfer para asegurarse de que los datos lleguen al cliente lo suficientemente rápido. Cuando tiene activado el almacenamiento en búfer, el proxy Nginx almacena temporalmente los datos de respuesta recibidos del servidor upstream backend. Luego, envía los datos al cliente según su velocidad. Una vez que Nginx tiene la respuesta en sus búferes, puede cerrar la conexión con el servidor backend. Luego distribuirá los datos al cliente a la velocidad que este admita. Al mismo tiempo, permite que el servidor backend continúe procesando otras solicitudes entrantes.

Por defecto, Nginx tendrá activado el almacenamiento en búfer. Esto se debe a que no podemos conocer las velocidades de conexión de los clientes. Los clientes suelen tener diferentes conexiones que pueden ser más lentas. A continuación, definiremos las diversas directivas que podemos especificar para ajustar el comportamiento de almacenamiento en búfer de Nginx. Las directivas se pueden definir en los contextos http, server o location; sin embargo, debe tener en cuenta que las directivas de tamaño se configuran por solicitud. Por lo tanto, aumentarlas más de lo absolutamente necesario puede afectar el rendimiento de su servidor cuando hay demasiadas solicitudes de clientes entrantes. Aquí están las directivas:

  • proxy_buffering – la directiva que controla si el almacenamiento en búfer está activo para un contexto particular y sus contextos secundarios. La configuración predeterminada para proxy_buffering es “on”.

  • proxy_buffer_size – la directiva que especifica el tamaño del búfer para almacenar las cabeceras encontradas en una respuesta de un servidor backend. Las cabeceras constituyen la primera parte de la respuesta de un servidor backend. El almacenamiento en búfer de estas cabeceras es independiente del resto de la respuesta. Por defecto, el tamaño establecido de este búfer es el mismo que el de proxy_buffers. Sin embargo, si la información de la cabecera es pequeña, puede establecer el tamaño en un valor inferior.

  • proxy_buffers – la directiva que controla el número (primer argumento) y el tamaño (segundo argumento) de los búferes para las respuestas proxy. La configuración predeterminada especifica 8 búferes de un tamaño igual a una página de memoria (ya sea 4k u 8k). Puede permitir el almacenamiento en búfer de más información aumentando el número de búferes.

  • proxy_max_temp_file_size – la directiva que especifica el tamaño máximo, por solicitud, para un archivo temporal en el disco. Los archivos temporales se crean cuando la respuesta upstream es demasiado grande para caber en un búfer.

  • proxy_busy_buffers_size – la directiva que especifica el tamaño máximo de los búferes que pueden pasar como “listos para el cliente” y, por lo tanto, ocupados. Un cliente solo puede leer los datos de un búfer a la vez. Sin embargo, los búferes están en una cola para enviarse al cliente en lotes. Puede especificar el tamaño del espacio de búfer permitido en este estado modificando esta directiva.

  • proxy_temp_file_write_size – la directiva que especifica la cantidad de datos que Nginx escribirá en el archivo temporal a la vez cuando la respuesta del servidor backend upstream sea demasiado grande para caber en los búferes configurados.

  • proxy_temp_path – la directiva que especifica la ruta a la ubicación en el disco donde Nginx debe almacenar los archivos temporales cuando la respuesta del servidor backend upstream sea demasiado grande para caber en los búferes configurados.

Nginx es altamente personalizable y le proporciona varias directivas para ajustar el comportamiento del almacenamiento en búfer. En la mayoría de los casos, los valores predeterminados funcionarán perfectamente. Al mismo tiempo, es bueno saber que puede ajustar algunos de estos valores para su implementación personalizada. Principalmente querrá ajustar las directivas proxy_buffers y proxy_buffer_size.

A continuación se muestra un ejemplo que aumenta el número de búferes de proxy disponibles para cada solicitud upstream. Hace eso al mismo tiempo que reduce el tamaño del búfer que almacena las cabeceras:

Veamos cómo puede servir datos más rápido a clientes rápidos desactivando por completo el almacenamiento en búfer. Si resulta que su cliente no es lo suficientemente rápido, Nginx utilizará automáticamente búferes. Sin embargo, primero enviará de inmediato los datos al cliente en lugar de esperar a los grupos de búferes. Esta configuración tiene una desventaja. Esta configuración hace que la conexión con el servidor upstream permanezca abierta para clientes lentos hasta que el cliente haya recibido todos los datos de la respuesta. Si el almacenamiento en búfer se establece en “off”, solo se utilizará el búfer definido por la directiva proxy_buffer_size. Aquí hay un fragmento que muestra cómo especificaría el almacenamiento en búfer desactivado:

  • Configuración de una infraestructura de alta disponibilidad (HA) (Configuración opcional)

Puede agregar un conjunto redundante de balanceadores de carga a la configuración del proxy Nginx para garantizar que sea más robusto y, por lo tanto, de alta disponibilidad. Una configuración de alta disponibilidad (HA) es una infraestructura sin un único punto de fallo. Los balanceadores de carga forman parte de esta configuración. Con más de un balanceador de carga, puede evitar posibles tiempos de inactividad si un balanceador de carga falla o se desconecta por mantenimiento.

Cómo implementar el almacenamiento en caché de proxy de Nginx para reducir los tiempos de respuesta

En la sección anterior, analizamos cómo utilizar el almacenamiento en búfer para liberar a los servidores backend para que puedan manejar más solicitudes. Nginx viene con otra característica que nos permite almacenar en caché los datos de respuesta del backend. Elimina por completo la necesidad de conectarse al upstream para todas las solicitudes entrantes.

Implementación de una caché de proxy

La directiva proxy_cache_path nos permite configurar una caché especificando un área en el disco para usar para almacenar contenido proxy. La directiva proxy_cache_path se define en el contexto http.

El siguiente fragmento de código de configuración es un ejemplo de cómo puede implementar un sistema de almacenamiento en caché:

En este fragmento de código, hemos utilizado la directiva proxy_cache_path para definir un directorio en el sistema de archivos que contendrá nuestra caché. El /var/lib/nginx/cache es el directorio que hemos establecido en este caso. Es libre de definir la ruta de directorio que prefiera. Utilice los siguientes comandos para crear los directorios elegidos, con los permisos y la propiedad correctos:

En el fragmento de código, el parámetro levels= especifica la organización de la caché. Nginx creará una clave de caché aplicando una función hash al valor de una clave (especificada mediante la directiva proxy_cache_key). Los niveles que especificamos (1:2) indican que se creará un directorio de un solo carácter (es decir, el último carácter del valor hash) con un subdirectorio de dos caracteres (tomado de los siguientes dos caracteres desde el final del valor hash). En la mayoría de los casos, esto no le afectará. Sin embargo, es bueno saber cómo ayuda a Nginx a encontrar rápidamente los valores relevantes.

El parámetro keys_zone= define el nombre de una zona de caché, en nuestro caso la hemos llamado backendcache. Aquí también definimos cuántos metadatos queremos almacenar. En este ejemplo, estamos almacenando 8 MB de claves. Nginx puede almacenar aproximadamente 8000 entradas por cada megabyte. El parámetro max_size especifica el tamaño máximo de los datos almacenados en caché reales, 50MB para nuestro ejemplo.

También debe notar la directiva proxy_cache_key utilizada. Esta directiva especifica la clave que utilizaremos para almacenar los valores almacenados en caché. Utilizaremos la misma clave para comprobar si la solicitud existe dentro de la caché. Hemos especificado que esa clave sea una combinación del esquema (http o https), el método de solicitud HTTP y el host y URI solicitados.

Además, hemos utilizado la directiva proxy_cache_valid. Esta directiva se puede especificar varias veces para varios códigos de estado. Nos permite especificar cuánto tiempo almacenar los valores según el código de estado. En el fragmento de código, especificamos 10 minutos para los códigos de éxito y 1 minuto para las respuestas 404.

Dado que hemos configurado la zona de caché, el siguiente paso es poner en práctica la configuración indicándole a Nginx cuándo usar la caché. A continuación se muestra un fragmento de configuración que muestra cómo podemos implementar el uso de esta caché:

En la directiva proxy_cache, hemos especificado que se debe utilizar la zona de caché backendcache para este contexto. Si eligió un nombre diferente en la configuración de la caché, aquí es donde lo reemplazará. Para cada entrada válida, Nginx verificará la caché antes de pasar una solicitud al servidor ascendente (upstream) del backend.

Definimos la directiva proxy_cache_bypass para usar la variable $http_cache_control. Esta variable le indica al servidor si debe responder con una respuesta almacenada en caché o con una versión nueva y no almacenada en caché del recurso. Configurar adecuadamente esta directiva permite a Nginx manejar correctamente varios tipos de solicitudes entrantes de los clientes.

También se especifica un encabezado adicional llamado X-Proxy-Cache. Este encabezado tiene el valor de la variable $upstream_cache_status. Nos brinda información sobre si la solicitud resultó en un acierto de caché (cache hit), un fallo de caché (cache miss) o si la caché se omitió explícitamente. Dicha información puede ser útil para el cliente y crucial durante la depuración de aplicaciones.

Puntos importantes sobre el almacenamiento en caché de resultados

Si bien el almacenamiento en caché mejorará enormemente el rendimiento de su servidor proxy, debe tener en cuenta lo siguiente al implementar el almacenamiento en caché:

Cualquier dato relacionado con la información personal de un usuario no debe almacenarse en caché, para evitar escenarios en los que los datos de un usuario sean visibles para otro usuario.

Sus servidores backend deben tener en cuenta todos los elementos dinámicos de su sitio web. Tenemos varios encabezados Cache-Control que podemos especificar en nuestra respuesta para cumplir diferentes propósitos. Analicémoslos:

  • no-cache – especifica que el proxy debe verificar si los datos han cambiado en el backend antes de servir una respuesta. Esto es aplicable para datos dinámicos e importantes. Se verifica un encabezado de metadatos con hash ETag en cada solicitud y, si el backend devuelve el mismo valor de hash, se sirve el valor anterior.

  • no-store – especifica que no se almacene en caché ningún dato recibido, por lo tanto, cada solicitud irá al servidor para obtener datos nuevos. Esto es lo más seguro para datos confidenciales.

  • private – especifica que ningún espacio de caché compartido debe almacenar los datos en caché. Puede usar este encabezado para especificar el almacenamiento en caché en el navegador del usuario, pero también para informar al servidor proxy que considere los datos como no válidos para solicitudes posteriores.

  • public – especifica una respuesta pública y permite el almacenamiento en caché en cualquier punto de la conexión.

Puede especificar cuánto tiempo desea que dure la caché en segundos utilizando el encabezado max-age. Los diversos encabezados definidos anteriormente pueden ayudarle a implementar el almacenamiento en caché mientras mantiene seguros los datos confidenciales, frescos los datos dinámicos y, lo más importante, mejora el rendimiento de su servidor.

Si sus servidores backend ejecutan servidores Nginx, puede especificar dentro de los bloques de servidor cuánto tiempo debe ser válida una caché. Puede hacerlo agregando la directiva expires a la configuración como se muestra a continuación:

El primer bloque permite el almacenamiento en caché del contenido durante 59 minutos, mientras que el segundo bloque indica que no se realice almacenamiento en caché. Estas configuraciones se aplican a las opciones de los encabezados Cache-Control, por ejemplo, “no-cache” para el segundo bloque.

Puede utilizar la directiva add-header para establecer valores adicionales:

Conclusión

En este tutorial, aprendimos sobre las potentes características de Nginx. Nginx es tanto un servidor web como, lo más importante, un proxy inverso. El diseño de Nginx le permite manejar miles de conexiones concurrentes. Esto lo hace perfecto para el equilibrio de carga. Debido a su diseño, el reenvío de solicitudes (proxying) a otros servidores backend para su procesamiento es bastante sencillo.

Con los conocimientos de este tutorial, deberías ser capaz de implementar proxies y balanceadores de carga complejos, gracias a la flexibilidad de Nginx.

Aquí tienes algunos recursos que puedes encontrar en nuestro blog que pueden ayudarte a familiarizarte más con Nginx:

¡Feliz computación!

author

Pranay Kapgate

Autor · CloudSigma

Preslav Dobrev es diseñador creativo en CloudSigma, centrado en una identidad empresarial coherente mediante el uso de canales de marketing tradicionales e innovadores. Es experto en fusionar la visión artística con el marketing estratégico para crear narrativas de marca impactantes.

Comentarios

Aún no hay comentarios. Sea el primero.