Antipatrón: Balanceo de cargas con un solo servidor de destino con MaxFailures configurado en un valor distinto de cero

Estás viendo la documentación de Apigee y Apigee Hybrid.
Consulta la documentación de Apigee Edge.

La configuración de TargetEndpoint define la forma en que Apigee se conecta a un servicio o API de backend. Envía las solicitudes y recibe las respuestas hacia y desde el servicio de backend. El servicio de backend puede ser un servidor HTTP/HTTPS o NodeJS.

El servicio de backend en TargetEndpoint se puede invocar de una de las siguientes maneras:

  • URL directa a un servidor HTTP o HTTPS
  • Configuración de TargetServer

Del mismo modo, la política ServiceCallout se puede usar para realizar una llamada a cualquier servicio externo desde el flujo del proxy de API. Esta política admite la definición de URL de destino HTTP/HTTPS directamente en la política o mediante una configuración de TargetServer.

Configuración de TargetServer

La configuración de TargetServer separa las URL de extremos concretas de las configuraciones de TargetEndpoint o de las políticas de texto destacado del servicio. Se hace referencia a un TargetServer por un nombre en lugar de la URL en TargetEndpoint. La configuración de TargetServer tendrá el nombre de host del servicio de backend, el número de puerto y otros detalles.

Esta es una muestra de configuración del TargetServer:

<TargetServer name="target1">
  <Host>www.mybackendservice.com</Host>
  <Port>80</Port>
  <IsEnabled>true</IsEnabled>
</TargetServer>

TargetServer te permite tener diferentes configuraciones para cada entorno. Una política TargetCallout/Service Callout se puede configurar con uno o más TargetServers con nombre mediante LoadBalancer. La compatibilidad integrada para el balanceo de cargas mejora la disponibilidad de las API y la conmutación por error entre las instancias de servidor de backend configuradas.

Esta es una muestra de configuración del TargetEndpoint mediante TargetServers:

<TargetEndpoint name="default">
    <HTTPTargetConnection>>
      <LoadBalancer>
        <Server name="target1"/>
        <Server name="target2"/>
      </LoadBalancer>
    </HTTPTargetConnection>
</TargetEndpoint>

MaxFailures

La configuración MaxFailures especifica la cantidad máxima de fallas de solicitudes para el servidor de destino después de la cual el servidor de destino se marcará como bloqueado y se quitará de la rotación de todas las solicitudes posteriores.

Una configuración de ejemplo con MaxFailures especificado es la siguiente:

<TargetEndpoint name="default">
    <HTTPTargetConnection>
      <LoadBalancer>
        <Server name="target1"/>
        <Server name="target2"/>
        <MaxFailures>5</MaxFailures>
      </LoadBalancer>
    </HTTPTargetConnection>
</TargetEndpoint>

En el ejemplo anterior, si cinco solicitudes consecutivas para “target1”, “target1” se quitará de la rotación y todas las solicitudes posteriores se enviarán solo a target2.

Antipatrón

No se recomienda tener un TargetServer único en una configuración LoadBalancer de la política TargetEndpoint o de políticas de texto destacado del servicio con MaxFailures establecido en un valor distinto de cero, ya que puede tener consecuencias adversas.

Considera la siguiente configuración de muestra que tiene un único TargetServer llamado “target1” con MaxFailures establecido en 5 (valor distinto de cero):

<TargetEndpoint name="default">
  <HTTPTargetConnection>
      <LoadBalancer>
        <Algorithm>RoundRobin</Algorithm>
        <Server name="target1" />
        <MaxFailures>5</MaxFailures>
      </LoadBalancer>
  </HTTPTargetConnection>

Si las solicitudes a TargetServer “target1” fallan cinco veces (número especificado en MaxFailures), el TargetServer se quita de la rotación. Dado que no hay otros TargetServers a los que conmutar por error, todas las solicitudes posteriores al proxy de API que tengan esta configuración fallarán con el error 503 Service Unavailable.

Incluso si el TargetServer "target1" vuelve a su estado normal y es capaz de enviar respuestas exitosas, las solicitudes al proxy de API seguirán mostrando errores 503. Esto se debe a que Apigee no vuelve a rotar el TargetServer de forma automática, incluso después de que el destino esté en funcionamiento otra vez. Para solucionar este problema, se debe volver a implementar el proxy de API a fin de que Apigee vuelva a rotar el TargetServer.

Si se usa la misma configuración en la política de texto destacado del servicio, las solicitudes a la API obtendrán un error 500 después de que las solicitudes a TargetServer “target1” fallen 5 veces.

Impacto

Usar un único TargetServer en una configuración LoadBalancer de la política TargetEndpoint o de llamada de servicio con MaxFailures establecido en un valor que no es cero, genera lo siguiente:

  • Las solicitudes a la API fallan con errores 503/500 de forma continua (después de que fallan las solicitudes para la cantidad de veces de MaxFailures) hasta que se vuelve a implementar el proxy de API.
  • La interrupción es más larga, ya que es complicada y puede tardar más en diagnosticar la causa de este problema (sin conocimiento previo sobre este antipatrón).

Práctica recomendada

  1. Tener más de un TargetServer en la configuración de LoadBalancer para obtener mayor disponibilidad.
  2. Siempre define un Monitor de estado cuando MaxFailures se configure en un valor distinto de cero. Se quitará un servidor de destino de la rotación cuando la cantidad de fallas alcance la cantidad especificada en MaxFailures. Tener un Monitor de estado garantiza que el TargetServer se vuelva a rotar tan pronto como el servidor de destino vuelva a estar disponible, lo que significa que no es necesario volver a implementar el proxy.

    A fin de garantizar que la verificación de estado se realice en el mismo número de puerto que Apigee usa para conectarse a los servidores de destino, Apigee recomienda que omitas el elemento secundario <Port> en <TCPMonitor> a menos que sea diferente del puerto TargetServer. De forma predeterminada, <Port> es el mismo que el puerto de TargetServer.

    Configuración de muestra con HealthMonitor:

    <TargetEndpoint name="default">
      <HTTPTargetConnection>
        <LoadBalancer>
          <Algorithm>RoundRobin</Algorithm>
          <Server name="target1" />
          <Server name="target2" />
          <MaxFailures>5</MaxFailures>
        </LoadBalancer>
        <Path>/test</Path>
        <HealthMonitor>
          <IsEnabled>true</IsEnabled>
          <IntervalInSec>5</IntervalInSec>
          <TCPMonitor>
            <ConnectTimeoutInSec>10</ConnectTimeoutInSec>
          </TCPMonitor>
        </HealthMonitor>
      </HTTPTargetConnection>
    </TargetEndpoint>
  3. Si existe alguna restricción como ese solo TargetServer y si no se usa HealthMonitor, no especifiques MaxFailures en la configuración LoadBalancer.

    El valor predeterminado de MaxFailures es 0. Esto significa que Apigee siempre intenta conectarse al destino de cada solicitud y nunca quita el servidor de destino de la rotación.

Lecturas adicionales