La mayoría de los balanceadores de cargas utilizan un método de generación de hash de turno rotativo o basado en flujo para distribuir el tráfico. Los balanceadores de cargas que utilizan este enfoque pueden tener dificultades para adaptarse cuando la demanda de tráfico aumenta más allá de la capacidad de entrega disponible. En este instructivo, se muestra cómo Cloud Load Balancing optimiza la capacidad de tu aplicación global, lo que da como resultado una mejor experiencia del usuario y menores costos en comparación con la mayoría de las implementaciones de balanceo de cargas.
Este artículo forma parte de una serie de recomendaciones para productos de Cloud Load Balancing. Este instructivo está acompañado por Optimizaciones de la capacidad de la aplicación con balanceo de cargas global, un artículo conceptual que explica los mecanismos subyacentes del desbordamiento de balanceo de cargas global con más detalle. Para obtener información más detallada sobre la latencia, consulta Optimiza la latencia de las aplicaciones con Cloud Load Balancing.
Para este instructivo, suponemos que tienes experiencia con Compute Engine. También debes estar familiarizado con los principios básicos del balanceador de cargas de aplicaciones externo.
Objetivos
En este instructivo, configuras un servidor web simple que ejecuta una aplicación que hace un uso intensivo de la CPU que calcula los conjuntos de Mandelbrot. Para comenzar, debes medir la capacidad de tu red mediante las herramientas de prueba de carga (siege y httperf). A continuación, escalas la red a varias instancias de VM en una sola región y mides el tiempo de respuesta bajo carga. Finalmente, puedes escalar la red a varias regiones con el balanceo de cargas global y luego medir el tiempo de respuesta del servidor bajo carga y compararlo con el balanceo de cargas de una sola región. Realizar esta secuencia de pruebas te permite ver los efectos positivos de la administración de carga interregional de Cloud Load Balancing.
La velocidad de comunicación de la red de una arquitectura típica de servidor de tres niveles suele estar limitada por la velocidad del servidor de la aplicación o la capacidad de la base de datos, y no por la carga de la CPU en el servidor web. Después de realizar el instructivo, puedes utilizar las mismas herramientas de prueba de carga y la configuración de capacidad para optimizar el comportamiento de balanceo de cargas en una aplicación del mundo real.
Harás lo siguiente:
- Aprenderás a usar las herramientas de prueba de cargas (
siege
yhttperf
). - Determinarás la capacidad de entrega de una sola instancia de VM.
- Medirás los efectos de la sobrecarga con el balanceo de cargas de una sola región.
- Medirás los efectos del desbordamiento a otra región con balanceo de cargas global.
Costos
En este instructivo, se usan los siguientes componentes facturables de Google Cloud:
- Compute Engine
- Balanceo de cargas y reglas de reenvío
Usa la calculadora de precios para generar una estimación de los costos según el uso previsto.
Antes de comenzar
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine API.
Configura tu entorno
En esta sección, definirás la configuración del proyecto, la red de VPC y las reglas básicas de firewall que necesitas para completar el instructivo.
Inicia una instancia de Cloud Shell
Abre Cloud Shell desde la consola de Google Cloud. A menos que se indique lo contrario, ejecuta el resto del instructivo desde dentro de Cloud Shell.
Define la configuración del proyecto
Con el fin de facilitar la ejecución de los comandos de gcloud
, puedes configurar propiedades a fin de no tener que proporcionar opciones para estas propiedades con cada comando.
Para establecer tu proyecto predeterminado, usa el ID de tu proyecto en
[PROJECT_ID]
:gcloud config set project [PROJECT_ID]
Si deseas establecer tu zona predeterminada de Compute Engine, ingresa tu zona preferida en
[ZONE]
y, luego, fija esta configuración como una variable de entorno para usarla más adelante:gcloud config set compute/zone [ZONE] export ZONE=[ZONE]
Crea y configura la red de VPC
Crea una red de VPC para probar lo siguiente:
gcloud compute networks create lb-testing --subnet-mode auto
Define una regla de firewall para permitir el tráfico interno:
gcloud compute firewall-rules create lb-testing-internal \ --network lb-testing --allow all --source-ranges 10.128.0.0/11
Define una regla de firewall para permitir que el tráfico SSH se comunique con la red de VPC:
gcloud compute firewall-rules create lb-testing-ssh \ --network lb-testing --allow tcp:22 --source-ranges 0.0.0.0/0
Cómo determinar la capacidad de entrega de una sola instancia de VM
Para examinar las características de rendimiento de un tipo de instancia de VM, harás lo siguiente:
Configura una instancia de VM que entregue la carga de trabajo de ejemplo (la instancia del servidor web).
Crea una segunda instancia de VM en la misma zona (la instancia de prueba de carga).
Con la segunda instancia de VM, medirás el rendimiento con herramientas simples de prueba de carga y de medición de rendimiento. Utilizarás estas medidas más adelante en el instructivo para ayudar a definir la configuración correcta de la capacidad de balanceo de cargas del grupo de instancias.
La primera instancia de VM utiliza una secuencia de comandos de Python para crear una tarea con un uso intensivo de la CPU calculando y mostrando una imagen de un conjunto de Mandelbrot en cada solicitud a la ruta raíz (/). El resultado no se almacena en caché. Durante el instructivo, obtendrás la secuencia de comandos de Python desde el repositorio de GitHub que se usó para esta solución.
Configura las instancias de VM
Instala y, luego, inicia el servidor de Mandelbrot a fin de configurar la instancia de VM de
webserver
como una instancia de VM de 4 núcleos:gcloud compute instances create webserver --machine-type n1-highcpu-4 \ --network=lb-testing --image-family=debian-10 \ --image-project=debian-cloud --tags=http-server \ --metadata startup-script='#! /bin/bash apt-get -y update apt-get install -y git python-numpy python-matplotlib git clone \ https://github.com/GoogleCloudPlatform/lb-app-capacity-tutorial-python.git cd lb-app-capacity-tutorial-python python webserver.py'
Crea una regla de firewall para permitir el acceso externo a la instancia de
webserver
desde tu propia máquina:gcloud compute firewall-rules create lb-testing-http \ --network lb-testing --allow tcp:80 --source-ranges 0.0.0.0/0 \ --target-tags http-server
Obtén la dirección IP de la instancia de
webserver
:gcloud compute instances describe webserver \ --format "value(networkInterfaces[0].accessConfigs[0].natIP)"
En un navegador web, ve a la dirección IP que muestra el comando anterior. Verás un conjunto de Mandelbrot computado:
Crea la instancia de prueba de carga:
gcloud compute instances create loadtest --machine-type n1-standard-1 \ --network=lb-testing --image-family=debian-10 \ --image-project=debian-cloud
Cómo probar las instancias de VM
El siguiente paso es ejecutar solicitudes para medir las características de rendimiento de la instancia de VM de prueba de carga.
Usa el comando de
ssh
para conectarte a la instancia de VM de prueba de carga:gcloud compute ssh loadtest
Instala siege y httperf en la instancia de prueba de carga como tus herramientas de prueba de carga:
sudo apt-get install -y siege httperf
La herramienta
siege
permite simular solicitudes de un número específico de usuarios, y realiza solicitudes subsiguientes una vez que los usuarios hayan recibido una respuesta. Esto te proporciona información valiosa sobre la capacidad y los tiempos de respuesta esperados para las aplicaciones en un entorno real.La herramienta
httperf
permite enviar una cantidad específica de solicitudes por segundo sin importar si se reciben respuestas o errores. Esto te proporciona información valiosa sobre cómo las aplicaciones responden a una carga específica.Mide el tiempo de una solicitud simple al servidor web:
curl -w "%{time_total}\n" -o /dev/#objectives_2 -s webserver
Obtienes una respuesta como 0.395260. Esto significa que el servidor tardó 395 milisegundos (ms) para responder a tu solicitud.
Usa el siguiente comando para ejecutar 20 solicitudes de 4 usuarios en paralelo:
siege -c 4 -r 20 webserver
Verás un resultado similar al siguiente:
** SIEGE 4.0.2 ** Preparing 4 concurrent users for battle. The server is now under siege... Transactions: 80 hits Availability: 100.00 % Elapsed time: 14.45 secs Data transferred: 1.81 MB Response time: 0.52 secs Transaction rate: 5.05 trans/sec Throughput: 0.12 MB/sec Concurrency: 3.92 Successful transactions: 80 Failed transactions: 0 **Longest transaction: 0.70 Shortest transaction: 0.37 **
La salida se explica completamente en el manual de siege, pero en este ejemplo puedes ver que los tiempos de respuesta variaron entre 0.37 s y 0.7 s. En promedio, se respondieron 5.05 solicitudes por segundo. Estos datos ayudan a estimar la capacidad de entrega del sistema.
Ejecuta los siguientes comandos para validar los resultados mediante la herramienta de prueba de cargas
httperf
:httperf --server webserver --num-conns 500 --rate 4
Este comando ejecuta 500 solicitudes a una velocidad de 4 solicitudes por segundo, es decir, menos que las 5.05 transacciones por segundo que completó
siege
.Verás un resultado similar al siguiente:
httperf --client=0/1 --server=webserver --port=80 --uri=/ --rate=4 --send-buffer=4096 --recv-buffer=16384 --num-conns=500 --num-calls=1 httperf: warning: open file limit > FD_SETSIZE; limiting max. # of open files to FD_SETSIZE Maximum connect burst length: 1 Total: connections 500 requests 500 replies 500 test-duration 125.333 s Connection rate: 4.0 conn/s (251.4 ms/conn, <=2 concurrent connections) **Connection time [ms]: min 369.6 avg 384.5 max 487.8 median 377.5 stddev 18.0 Connection time [ms]: connect 0.3** Connection length [replies/conn]: 1.000 Request rate: 4.0 req/s (251.4 ms/req) Request size [B]: 62.0 Reply rate [replies/s]: min 3.8 avg 4.0 max 4.0 stddev 0.1 (5 samples) Reply time [ms]: response 383.8 transfer 0.4 Reply size [B]: header 117.0 content 24051.0 footer 0.0 (total 24168.0) Reply status: 1xx=0 2xx=100 3xx=0 4xx=0 5xx=0 CPU time [s]: user 4.94 system 20.19 (user 19.6% system 80.3% total 99.9%) Net I/O: 94.1 KB/s (0.8*10^6 bps) Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0 Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0
El resultado se explica en el archivo README de httperf. Préstale atención a la línea que comienza con
Connection time [ms]
, en la que se muestra que las conexiones tomaron entre 369.6 ms y 487.8 ms en total y que no generaron ningún error.Repite la prueba 3 veces y establece la opción
rate
en 5, 7 y 10 solicitudes por segundo.En los siguientes bloques, se muestran los comandos de
httperf
y sus resultados (solo se muestran las líneas relevantes con información sobre el tiempo de conexión).Comando para 5 solicitudes por segundo:
httperf --server webserver --num-conns 500 --rate 5 2>&1| grep 'Errors\|ion time'
Resultados para 5 solicitudes por segundo:
Connection time [ms]: min 371.2 avg 381.1 max 447.7 median 378.5 stddev 7.2 Connection time [ms]: connect 0.2 Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0 Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0
Comando para 7 solicitudes por segundo:
httperf --server webserver --num-conns 500 --rate 7 2>&1| grep 'Errors\|ion time'
Resultados para 7 solicitudes por segundo:
Connection time [ms]: min 373.4 avg 11075.5 max 60100.6 median 8481.5 stddev 10284.2 Connection time [ms]: connect 654.9 Errors: total 4 client-timo 0 socket-timo 0 connrefused 0 connreset 4 Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0
Comando para 10 solicitudes por segundo:
httperf --server webserver --num-conns 500 --rate 10 2>&1| grep 'Errors\|ion time'
Resultados para 10 solicitudes por segundo:
Connection time [ms]: min 374.3 avg 18335.6 max 65533.9 median 10052.5 stddev 16654.5 Connection time [ms]: connect 181.3 Errors: total 32 client-timo 0 socket-timo 0 connrefused 0 connreset 32 Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0
Sal de la instancia de
webserver
:exit
A partir de estas mediciones, se puede determinar que el sistema tiene una capacidad de alrededor de 5 solicitudes por segundo (RPS). A 5 solicitudes por segundo, la instancia de VM reacciona con una latencia comparable a 4 conexiones. A 7 y 10 conexiones por segundo, el tiempo de respuesta promedio aumenta considerablemente a más de 10 segundos con varios errores de conexión. En otras palabras, cualquier cosa que exceda las 5 solicitudes por segundo causa una desaceleración significativa.
En un sistema más complejo, la capacidad del servidor se determina de manera similar, pero depende, en gran medida, de la capacidad de todos sus componentes. Puedes usar las herramientas siege
y httperf
junto con la CPU y la supervisión de cargas de E/S de todos los componentes (por ejemplo, el servidor de frontend, el servidor de aplicaciones, el servidor de bases de datos) para ayudar a identificar los cuellos de botella. Esto, a su vez, puede ayudarte a habilitar el escalamiento óptimo para cada componente.
Mide los efectos de la sobrecarga con un balanceador de cargas de una sola región
En esta sección, examinarás los efectos de la sobrecarga en los balanceadores de cargas de una sola región, como los balanceadores de cargas típicos utilizados localmente o el balanceador de cargas de red de transferencia externo de Google Cloud. También puedes observar este efecto con un balanceador de cargas de HTTP(S) cuando el balanceador de cargas se usa para una implementación regional (en lugar de una global).
Crea el balanceador de cargas de HTTP(S) de una sola región
Los siguientes pasos describen cómo crear un balanceador de cargas de HTTP(S) de una sola región con un tamaño fijo de 3 instancias de VM.
Crea una plantilla de instancias para las instancias de VM del servidor web con la secuencia de comandos de generación de Mandelbrot en Python que usaste anteriormente. Ejecuta los siguientes comandos en Cloud Shell:
gcloud compute instance-templates create webservers \ --machine-type n1-highcpu-4 \ --image-family=debian-10 --image-project=debian-cloud \ --tags=http-server \ --network=lb-testing \ --metadata startup-script='#! /bin/bash apt-get -y update apt-get install -y git python-numpy python-matplotlib git clone \ https://github.com/GoogleCloudPlatform/lb-app-capacity-tutorial-python.git cd lb-app-capacity-tutorial-python python webserver.py'
Crea un grupo de instancias administrado con 3 instancias basadas en la plantilla del paso anterior:
gcloud compute instance-groups managed create webserver-region1 \ --size=3 --template=webservers
Crea la verificación de estado, el servicio de backend, el mapa de URL, el proxy de destino y la regla de reenvío global necesarios para generar el balanceo de cargas de HTTP:
gcloud compute health-checks create http basic-check \ --request-path="/health-check" --check-interval=60s gcloud compute backend-services create web-service \ --health-checks basic-check --global gcloud compute backend-services add-backend web-service \ --global --instance-group=webserver-region1 \ --instance-group-zone $ZONE gcloud compute url-maps create web-map --default-service web-service gcloud compute target-http-proxies create web-proxy --url-map web-map gcloud compute forwarding-rules create web-rule --global \ --target-http-proxy web-proxy --ports 80
Obtén la dirección IP de la regla de reenvío:
gcloud compute forwarding-rules describe --global web-rule --format "value(IPAddress)"
El resultado es la dirección IP pública del balanceador de cargas que creaste.
Ve a la dirección IP desde un navegador para ver el comando anterior. Después de unos minutos, verás la misma imagen de Mandelbrot que viste anteriormente. Sin embargo, esta vez la imagen se entrega desde una de las instancias de VM en el grupo recién creado.
Accede a la máquina de
loadtest
:gcloud compute ssh loadtest
En la línea de comandos de la máquina de
loadtest
, prueba la respuesta del servidor con diferentes cantidades de solicitudes por segundo (RPS). Asegúrate de usar valores de RPS que se encuentren al menos en el rango comprendido entre 5 y 20.Por ejemplo, con el siguiente comando se generan 10 RPS. Reemplaza
[IP_address]
por la dirección IP del balanceador de cargas de un paso anterior de este procedimiento.httperf --server [IP_address] --num-conns 500 --rate 10 2>&1| grep 'Errors\|ion time'
La latencia de la respuesta aumenta de manera significativa a medida que la cantidad de RPS aumenta más allá de 12 o 13 RPS. A continuación, se ilustran los resultados típicos:
Sal de la instancia de VM de
loadtest
:exit
Este rendimiento es típico de un sistema de cargas balanceadas de forma regional. A medida que la carga aumenta más allá de la capacidad de entrega, aumentan de forma considerable el promedio de latencia de solicitud, al igual que su valor máximo. Con 10 RPS, la latencia de solicitud promedio es alrededor de 500 ms, pero con 20 RPS, la latencia es de 5,000 ms. La latencia se multiplicó por diez y la experiencia del usuario se deteriora con rapidez, lo que provoca que los usuarios abandonen la aplicación o que se agote el tiempo de espera de esta, o bien ambas opciones.
En la siguiente sección, agregarás una segunda región a la topología del balanceo de cargas y compararás cómo la conmutación por error entre regiones afecta la latencia del usuario final.
Mide los efectos de desbordamiento a otra región
Si usas una aplicación global con un balanceador de cargas de aplicaciones externo y si tienes backends implementados en varias regiones, cuando se produce una sobrecarga de capacidad en una sola región, el tráfico fluye automáticamente a otra región. Puedes validar esto si agregas un segundo grupo de instancias de VM en otra región a la configuración que creaste en la sección anterior.
Crea servidores en varias regiones
En los siguientes pasos, agregarás otro grupo de backends en otra región y asignarás una capacidad de 10 RPS por región. Luego puedes ver cómo reacciona el balanceo de cargas cuando se excede este límite.
Elige una zona en una región diferente a tu zona predeterminada en Cloud Shell, y configúrala como una variable de entorno:
export ZONE2=[zone]
Crea un nuevo grupo de instancias en la segunda región con 3 instancias de VM:
gcloud compute instance-groups managed create webserver-region2 \ --size=3 --template=webservers --zone $ZONE2
Agrega el grupo de instancias al servicio de backend existente con una capacidad máxima de 10 RPS:
gcloud compute backend-services add-backend web-service \ --global --instance-group=webserver-region2 \ --instance-group-zone $ZONE2 --max-rate 10
Establece
max-rate
en 10 RPS para el servicio de backend existente:gcloud compute backend-services update-backend web-service \ --global --instance-group=webserver-region1 \ --instance-group-zone $ZONE --max-rate 10
Después de iniciar todas las instancias, accede a la instancia de VM de
loadtest
:gcloud compute ssh loadtest
Ejecuta 500 solicitudes a 10 RPS. Reemplaza
[IP_address]
por la dirección IP del balanceador de cargas:httperf --server [IP_address] --num-conns 500 --rate 10 2>&1| grep 'ion time'
Deberías ver un resultado como el siguiente:
Connection time [ms]: min 405.9 avg 584.7 max 1390.4 median 531.5 stddev 181.3 Connection time [ms]: connect 1.1
Los resultados son similares a los producidos por el balanceador de cargas regional.
Debido a que tu herramienta de prueba ejecuta de inmediato una carga completa y no aumenta poco a poco la carga como una implementación real, debes repetir la prueba un par de veces para que el mecanismo de desbordamiento se aplique. Ejecuta 500 solicitudes 5 veces a 20 RPS. Reemplaza
[IP_address]
por la dirección IP del balanceador de cargas.for a in \`seq 1 5\`; do httperf --server [IP_address] \ --num-conns 500 --rate 20 2>&1| grep 'ion time' ; done
Deberías ver un resultado como el siguiente:
Connection time [ms]: min 426.7 avg 6396.8 max 13615.1 median 7351.5 stddev 3226.8 Connection time [ms]: connect 0.9 Connection time [ms]: min 417.2 avg 3782.9 max 7979.5 median 3623.5 stddev 2479.8 Connection time [ms]: connect 0.9 Connection time [ms]: min 411.6 avg 860.0 max 3971.2 median 705.5 stddev 492.9 Connection time [ms]: connect 0.7 Connection time [ms]: min 407.3 avg 700.8 max 1927.8 median 667.5 stddev 232.1 Connection time [ms]: connect 0.7 Connection time [ms]: min 410.8 avg 701.8 max 1612.3 median 669.5 stddev 209.0 Connection time [ms]: connect 0.8
Después de que el sistema se estabilice, el tiempo de respuesta promedio es de 400 ms a 10 RPS y solo aumenta a 700 ms a 20 RPS. Esta es una gran mejora con respecto a la demora de 5,000 ms ofrecida por un balanceador de cargas regional, y da como resultado una experiencia del usuario mucho mejor.
En el siguiente gráfico, se muestra el tiempo de respuesta medido por RPS con el balanceo de cargas global:
Compara los resultados del balanceo de cargas regional y el global
Una vez que hayas establecido la capacidad de un solo nodo, podrás comparar la latencia observada por los usuarios finales en una implementación basada en la región con la latencia en una arquitectura de balanceo de cargas global. Aunque la cantidad de solicitudes en una sola región es inferior a la capacidad de entrega total en esa región, ambos sistemas tienen una latencia similar para el usuario final, porque los usuarios siempre son redireccionados a la región más cercana.
Cuando la carga a una región supera la capacidad de entrega para esa región, la latencia del usuario final difiere significativamente entre las soluciones:
Las soluciones de balanceo de cargas regional se sobrecargan cuando el tráfico aumenta más allá de la capacidad, ya que el tráfico solo puede fluir a las instancias de VM de backend sobrecargadas. Esto incluye los balanceadores de cargas locales tradicionales, los balanceadores de cargas de red de transferencia externos en Google Cloud y los balanceadores de cargas de aplicaciones externos en una configuración de una sola región (por ejemplo, mediante las herramientas de redes del nivel Estándar). Las latencias promedio y máximas de solicitud aumentan por más de un factor de 10, lo que produce experiencias de usuario deficientes que, a su vez, podrían llevar a un abandono significativo de usuarios.
Los balanceadores de cargas de aplicaciones externos globales con backends en varias regiones permiten que el tráfico se desborde hacia la región más cercana que tenga capacidad de entrega disponible. Esto produce un aumento que se puede medir, pero que es comparativamente bajo, en la latencia del usuario final y proporciona una experiencia del usuario mucho mejor. Si tu aplicación no puede escalar en una región lo suficientemente rápido, la opción recomendada es el balanceador de cargas de aplicaciones externo global. Incluso durante una falla en la región completa de los servidores de aplicaciones del usuario, el tráfico se redirecciona rápidamente a otras regiones y ayuda a evitar una interrupción total del servicio.
Limpia
Borra el proyecto
La manera más fácil de eliminar la facturación es borrar el proyecto que creaste para el instructivo.
Para borrar el proyecto, sigue estos pasos:
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
Próximos pasos
Las siguientes páginas proporcionan más información y antecedentes sobre las opciones de balanceo de cargas de Google:
- Optimiza la latencia de las aplicaciones con Cloud Load Balancing
- Codelab para Herramientas de redes 101
- Balanceador de cargas de red de transferencia externo
- Balanceador de cargas de aplicaciones externo
- Balanceador de cargas de red del proxy externo