Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

Prefacio

Creo que después de los artículos anteriores, todos tienen una comprensión clara del proceso general de Dubbo, incluido cómo se expone el servicio, cuándo se registra el servicio en el registro, cómo se introduce el servicio, el proceso de invocación general del servicio, etc.

Sin embargo, hay otro punto muy importante que no se ha discutido en profundidad, que es la tolerancia a fallas de clúster de Dubbo.

Los servicios en línea deben implementarse en grupos. Se requieren al menos dos para respaldarse entre sí. Entonces la pregunta es, ¿a qué proveedor debe elegir llamar el consumidor de servicios? ¿Qué debo hacer si falla la llamada?

En este momento, la función de tolerancia a fallas de clúster es útil. Hoy analizaremos en profundidad una ola de tolerancia a fallas de clúster de Dubbo.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

¿Qué es un invocador?

De hecho, lo he dicho antes, así que lo volveré a revisar hoy porque es realmente importante.

En Dubbo, el invocador es en realidad un objeto con una función de llamada, lo que se encapsula en el lado de la exposición del servicio es la implementación del servicio real y la implementación del servicio real se encapsula en un invocador.

En el lado de la introducción del servicio, la información de configuración del proveedor de servicios se obtiene del registro, y luego se encapsula una parte de la información de configuración en un invocador. Este invocador tiene la capacidad de llamar de forma remota. Por supuesto, si se usa el protocolo injvm, se toma la llamada real o local.

Luego está un ClusterInvoker, que también es un invocador, que encapsula los invocadores generados por la introducción del servicio y le da al clúster tolerancia a fallas y otras capacidades.Este invocador es el invocador expuesto a los consumidores.

Entonces, Dubbo es un modelo unificado que encapsula todos los objetos de servicio que se pueden llamar a un invocador.

Hoy hablamos principalmente de servir a los consumidores, porque la tolerancia a fallas del clúster se implementa en el lado del consumidor.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

¿Qué es exactamente un catálogo de servicios?

El directorio de servicios también es el Directorio. De hecho, se introdujo antes, pero no se describió por separado. Puede que no sea claro para todos. Echemos un vistazo hoy.

¿Qué es exactamente un catálogo de servicios? ¿Parece que el nombre es un catálogo de servicios, a través del cual se pueden encontrar servicios remotos?

¡Mitad a la derecha! Puede encontrar servicios remotos a través del directorio de servicios, pero no es un "directorio", de hecho, es una colección de varios invocadores,

Como se mencionó anteriormente, los proveedores de servicios se implementarán en clústeres. Habrá múltiples proveedores para todos los mismos servicios. Por lo tanto, configuraremos un catálogo de servicios para recopilarlos. Cuando desee elegir, elegirá del catálogo de servicios.

Y los proveedores de servicios no son estáticos. Por ejemplo, si se agrega un proveedor de servicios al clúster, entonces se debe agregar un invocador al catálogo de servicios correspondiente, un proveedor de servicios está fuera de línea y el invocador correspondiente debe eliminarse del catálogo. La configuración modificada también debe actualizarse.

Entonces, este directorio de servicios implementa la función de monitorear el registro (refiriéndose a RegistryDirectory).
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

Este nodo se deja solo. Depende principalmente del directorio. Para el funcionamiento normal, se utiliza una clase abstracta para implementar la interfaz del directorio. La clase abstracta implementa algunos métodos públicos y define la lógica. Luego, la implementación específica la completa la subclase. Puede ver que hay dos Las subcategorías son StaticDirectory y RegistryDirectory.

RegistryDirectory

Primero echemos un vistazo a RegistryDirectory, es un directorio dinámico, echemos un vistazo a la estructura específica.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

En la captura de pantalla, puede ver que RegistryDirectory almacena las dos URL del proveedor de servicios de DemoService y los invocadores correspondientes.

Y de la estructura de herencia anterior, también se puede ver que implementa la interfaz NotifyListener, por lo que puede monitorear los cambios en el registro. Cuando cambia la configuración del centro de servicio, RegistryDirectory puede recibir una notificación del cambio y luego actualizar su lista de Invoker de acuerdo con la configuración .

Entonces, hay tres funciones de RegistryDirectory:

  1. Obtener la lista de invocadores
  2. Supervisar cambios en el registro
  3. Actualizar los invocadores.

Para obtener la lista de invocadores, el método abstracto de clase padre doList implementado por RegistryDirectory tiene como objetivo obtener la lista de invocadores, y su implementación interna es principalmente para filtrar los nombres de los métodos de capa y encontrar los correspondientes invocadores por el nombre del método.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

Supervise los cambios en el registro y observe los cambios de datos en el registro mediante la implementación de la interfaz NotifyListener, que en realidad se suscribe cuando se introduce el servicio.

 public void subscribe(URL url) {
        setConsumerUrl(url);
        registry.subscribe(url, this); //订阅
    }

RegistryDirectory define tres colecciones, a saber, invokerUrls, routerUrls y configuratorUrls para manejar los cambios de configuración correspondientes y luego convertirlos en objetos.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

Actualizar la lista de Invoker es en realidad realizar una ola de operaciones basadas en las InvokerUrls que monitorean los cambios, actualizanInvoker (invokerUrls) y actualizan los Invocadores de acuerdo con la configuración.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

En pocas palabras, primero decida si deshabilitar todos los invocadores en función del número de invokerUrls y si el encabezado del protocolo está vacío. De lo contrario, convierta la URL en Invoker para obtener la relación de mapeo de <url, Invoker>.

Luego, realice la conversión para obtener la relación de mapeo de <nombre del método, lista de invocador>, luego combine los Invocadores del mismo grupo y asigne el resultado combinado a methodInvokerMap. Este methodInvokerMap es el mapa usado en doList arriba.

Entonces, el methodInvokerMap se construye durante refreshInvoker, y luego se lee el methodInvokerMap al llamar y finalmente se destruye el invocador inútil.

StaticDirectory

StaticDirectory, este se usa en múltiples registros, es un directorio estático, es decir, es fijo y no aumentará ni disminuirá, todos los Invocadores se pasan a través del constructor.

Se puede entender simplemente que una referencia que configuramos bajo un solo registro puede corresponder a múltiples proveedores, para luego generar múltiples facturas, las almacenamos en el RegistryDirectory para su gestión, con el fin de facilitar la llamada, solo se expone una factura al exterior para encapsular Situación interna de múltiples invocadoras.

Los múltiples registros tendrán múltiples invocadores encapsulados, que nuevamente enfrentan una opción, por lo que usamos StaticDirectory para almacenar estos invocadores para su administración y luego los encapsulamos para exponer solo un invocador para llamadas fáciles.

Es estático porque se escriben varios registros en la configuración, a diferencia de los servicios que se pueden cambiar de forma dinámica.

La lógica interna de StaticDirectory es muy simple, es decir, una lista almacena estos invocadores, y luego el método de la clase padre simplemente devuelve la lista sin realizar ninguna operación.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

¿Qué es el enrutamiento de servicios?

El enrutamiento de servicios es en realidad reglas de enrutamiento, que especifican a qué proveedores de servicios pueden llamar los consumidores de servicios. Dubbo tiene tres rutas: ConditionRouter, ScriptRouter y TagRouter.

El más utilizado es el enrutamiento condicional, analizaremos el enrutamiento condicional.

El enrutamiento condicional se compone de dos condiciones, en el formato [condición de coincidencia del consumidor de servicios] => [condición de coincidencia del proveedor de servicios], por ejemplo, el sitio web oficial es host = 10.20.153.10 => host = 10.20.153.11.

Esta regla indica que los consumidores de servicios con IP 10.20.153.10 solo pueden llamar a servicios en máquinas con IP 10.20.153.11 y no pueden llamar a servicios en otras máquinas.

A esto se le llama enrutamiento.

La configuración de enrutamiento también se actualiza y construye a través de la notificación de RegistryDirectory, y luego la llamada de enrutamiento es para actualizar el invocador, específicamente cuando se llama a toMethodInvokers, se realizará enrutamiento a nivel de servicio y enrutamiento a nivel de método.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

La coincidencia de enrutamiento específica y el análisis de expresiones no serán en profundidad. Los estudiantes interesados ​​lo entenderán por sí mismos. De hecho, saben lo que hace esta función. De todos modos, después del filtrado de enrutamiento, los consumidores obtienen servicios remotos que pueden ser llamados.

¿Para qué sirve Dubbo's Cluster?

Ya hemos dicho que hay un catálogo de servicios, y el catálogo se ha filtrado por reglas de enrutamiento. En este momento, todavía tenemos un montón de invocadores. Los consumidores deben tomar una decisión. Entonces, ¿a cuál invocador debo llamar?

¿Qué debo hacer si el invocador seleccionado comete un error? Como mencionamos anteriormente, aquí es cuando el clúster entra en escena. Encapsulará este grupo de invocadores en clusterInovker, y solo se llamará a un invocador para los consumidores.

Luego, puede realizar varias operaciones dentro del clusterInovker, como seleccionar un invocador y cambiar uno si la llamada falla.

Estos detalles están encapsulados y los consumidores no pueden sentir esta complejidad, por lo que el clúster es una capa intermedia que protege a los consumidores del proveedor de servicios y simplifica el uso de los consumidores.

También es más conveniente reemplazar varias medidas de tolerancia a fallas del clúster.

Hay muchas implementaciones de clúster predeterminadas de Dubbo, principalmente las siguientes:
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

Cada Cluster devuelve XXXClusterInvoker. Permítanme darles un ejemplo de FailoverCluster.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

Simplemente baje y revisaremos cada grupo.

FailoverClusterInvoker

Este clúster implementa la función de conmutación por error automática.En pocas palabras, si una llamada remota falla, inmediatamente cambiará a otra, por supuesto, hay reintentos.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

Se puede ver que el método doInvoke primero obtiene el número de reintentos y luego realiza una llamada de bucle según el número de reintentos, detecta la excepción y luego vuelve a intentarlo después de la falla.

Cada ciclo seleccionará un invocador mediante el equilibrio de carga y luego realizará llamadas remotas a través de este invocador. Si falla, registrará la excepción y volverá a intentarlo.

Esta selección en realidad tiene un proceso pegajoso, es decir, registrará el último invocador seleccionado, por lo que cada llamada no siempre cambiará el invocador. Si no hay un invocador la última vez, o el invocador anterior se desconecta, se realizará el equilibrio de carga. Seleccione.

FailfastClusterInvoker

Este clúster solo realizará una llamada remota. Si se lanza una excepción inmediatamente después de la falla, fallará rápidamente. Es adecuado para llamadas que no admiten idempotencia.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

Como puede ver en el código, es muy simple seleccionar un invocador a través del equilibrio de carga, luego iniciar la llamada y lanzar un error si falla.

FailsafeClusterInvoker

Este clúster es un clúster a prueba de fallas, es decir, el error de llamada solo se registra en el registro y luego se devuelve un resultado vacío, que es adecuado para operaciones como escribir en el registro de auditoría.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

Puede ver que el código es muy simple, simplemente arroje un error y regístrelo, y devuelva un resultado vacío.

FailbackClusterInvoker

Este clúster registrará la llamada después de que la llamada falle, y luego devolverá un resultado vacío al consumidor del servicio y volverá a sintonizar la llamada fallida a través de una tarea programada.

Adecuado para escenarios de mejor esfuerzo, como notificación de mensajes.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

Parece mucho código, pero la lógica es muy simple.

Cuando la llamada falla, devuelve un resultado vacío y lo agrega a fallado, y habrá una tarea cronometrada que llamará periódicamente a la llamada fallida. Si la llamada es exitosa, elimine la llamada fallida.

BifurcaciónClusterInvoker

Este clúster realizará llamadas simultáneas a todos los invocadores a través del grupo de subprocesos en tiempo de ejecución. Siempre que un proveedor de servicios devuelva correctamente el resultado, el método doInvoke finalizará inmediatamente su operación.

Es adecuado para operaciones de lectura con altos requisitos de tiempo real.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

BroadcastClusterInvoker

Este clúster llamará a todos los invocadores uno por uno en tiempo de ejecución, y luego, al final, juzgará si una de las llamadas arroja un error, lanzará una excepción.

Es adecuado para notificar a todos los proveedores que actualicen la información de los recursos locales, como el caché o el registro.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

ResumenClústerInvoker

Esta es en realidad su clase padre, pero AvailableCluster devuelve internamente AbstractClusterInvoker. Esto se usa principalmente en múltiples registros. Es relativamente simple, solo use el que funcione.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

Grupo de resumen

Se puede ver que hay muchas implementaciones de clústeres anteriores, que son adecuadas para diferentes escenarios. En realidad, esta es una buena abstracción. La adición de esta capa intermedia protege a los consumidores de servicios de los detalles de las llamadas de clúster y pueden elegir más apropiados en diferentes escenarios. lograr.

Por supuesto, puede personalizar la implementación y ampliarla usted mismo para personalizar el esquema de llamada de enlace adecuado para su negocio.

Equilibrio de carga en Dubbo

El equilibrio de carga se divide en realidad en equilibrio de carga de hardware y equilibrio de carga de software. Todos deberían estar familiarizados con el equilibrio de carga de software, como Nginx.

Dubbo también tiene su propio equilibrio de carga, LoadBalance. Como mencionamos anteriormente, los proveedores de servicios generalmente se implementan en clústeres. Aunque este clúster expone un invocador para que los consumidores lo llamen, tiene que juzgar cuándo se llama realmente. Específicamente, a qué proveedor de servicios se va a llamar, entonces el equilibrio de carga está en escena.

Por lo tanto, el equilibrio de carga en Dubbo se utiliza para seleccionar un proveedor de servicios adecuado para llamar a los consumidores. De forma predeterminada, Dubbo proporciona una variedad de algoritmos de equilibrio de carga:
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

Veámoslo uno por uno. Aunque se trata de algoritmos, tiene poco efecto. Está bien entender el significado de forma aproximada. Por supuesto, es mejor entenderlos todos. Veamos primero la clase padre de estas clases de implementación.

ResumenCargaSaldo

Todas estas clases de implementación heredan de esta clase, que implementa la interfaz LoadBalance y encapsula alguna lógica común. También es un método de plantilla y una receta familiar.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

La lógica es muy simple. Echemos un vistazo al método de cálculo de pesos. Esta es una lógica común. De hecho, es para el precalentamiento del servicio. Sabemos que la memoria caché tiene precalentamiento y el JIT también tiene precalentamiento. La respuesta al servicio es que el servicio debe precalentarse.

Cuando el servicio recién se inicia, no puede dejar que se cargue demasiado la próxima vez, debe dejar que se caliente lentamente, además de cargar, por lo que este método juzgará el tiempo de ejecución del servicio para reducir la potencia del servicio, que es un método de optimización.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

Balance de carga aleatoria

Este algoritmo se pondera al azar y la idea es realmente muy simple. Permítanme dar un ejemplo: supongamos que hay dos servidores A y B. Quiero que el 70% de las solicitudes caigan en A y el 30% de las solicitudes en B. Esto En ese momento, solo necesito crear un rango de generación de números aleatorios en [0,10), este 10 se deriva de 7 + 3.

Entonces, si el número aleatorio obtenido está en [0,7), se selecciona el servidor A, y si está en [7,10), se selecciona el servidor B. Por supuesto, la probabilidad será correcta si el número aleatorio está bien distribuido.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

Ahora echemos un vistazo a cómo se realiza Dubbo El pensamiento es el pensamiento anterior.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

Se puede ver que es bastante simple. Por ejemplo, si el número aleatorio es 5, entonces 5-7 <0, entonces se selecciona A. Si el número aleatorio es 8, entonces 8-7 es mayor que 1, y luego 1-3 es menor que 0. Así que esto Cuando elegí B.

Esta es la implementación de equilibrio de carga adoptada por Dubbo por defecto.

MenosActiva Carga Saldo

Este es el balanceador de carga menos activo. Puede saber por el nombre para seleccionar el proveedor con las llamadas menos activas para realizar llamadas. El menor número de llamadas activas significa que ahora es muy fácil, y los números activos se suman desde 0 para realizar una solicitud El número activo es +1, y el número activo de una solicitud que se procesa es -1, por lo que una pequeña cantidad de activos puede reflejar la velocidad de procesamiento disfrazada.

Esta es en realidad la idea del número menos activo, y Dubbo usa el peso para juzgar cuando el número activo es igual.Este peso es en realidad el mismo que la implementación de RandomLoadBalance.

No publicaré el código. En pocas palabras, el proceso consiste en recorrer primero la lista de invocadores para encontrar el Invocador con el menor número de activos. Si hay varios Invocadores con el mismo número mínimo de activos, registre los subíndices de estos invocadores y agregue sus pesos. Para selección de peso.

Si solo hay un invocador con el número activo más pequeño, simplemente regrese directamente.

ConsistentHashLoadBalance

Este es un algoritmo de equilibrio de carga Hash consistente. El Hash consistente debe ser familiar para todos. El algoritmo Hash consistente común es propuesto por Karger, que consiste en establecer el espacio de valor hash en [0, 2 ^ 32-1], y es un bucle Forma de anillo.

Genere un valor hash a partir de la IP del servidor y otra información, proyecte este valor en el anillo como un nodo, y luego, cuando se busque la clave, busque el primer nodo con un valor hash mayor o igual a esta clave en el sentido de las agujas del reloj.

En términos generales, se introducirán nodos virtuales para que los datos estén más dispersos y evitar que la inclinación de los datos abrume a un nodo. Eche un vistazo a un gráfico en el sitio web oficial.

Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo
La implementación general no es difícil, es la lógica mencionada anteriormente, y el círculo se implementa usando treeMap, a través de tailMap para encontrar la primera factura mayor o igual a, si no encuentra las instrucciones para tomar la primera, asigne directamente La primera entrada de treeMap.

Entonces Dubbo tiene 160 nodos virtuales por defecto. El hash general es el nivel de método, es decir, cada método de un servicio tiene un ConsistentHashSelector, y el hash se realiza de acuerdo con el valor del parámetro, lo que significa que la lógica de equilibrio de carga solo se ve afectada por el valor del parámetro , Las solicitudes con el mismo valor de parámetro se asignarán al mismo proveedor de servicios.

Veamos primero la implementación de hash consistente, este virtualInvokers es TreeMap.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo
Entonces, echemos un vistazo a cómo obtener el invocador mediante un hash consistente.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

RondaRobinLoadBalance

Este es el balanceo de carga ponderado por turnos. Todos sabemos que el turno por turnos es por turnos ponderados. Por ejemplo, hay dos servidores A y B. El orden de las llamadas de sondeo es A, B, A, B. ..., si se suma el peso, el peso de A a B es 3: 1, entonces el orden de llamada actual es A, A, A, B, A, A, A, B ...

El motivo de la ponderación es que los servidores individuales tienen un mejor rendimiento, por lo que quiero sondear más.

Sin embargo, de esta manera, puede ver que A se solicita las primeras tres veces, y luego B. No es par. Suponga que es 90:80. Las primeras 90 veces presionan A. A está demasiado ocupado y B no tiene espacio. Por lo que debe suavizarse.

Este tipo de encuesta ponderada suave es mejor, como A, B, A, A, B, A ... En pocas palabras, son encuestas en desorden.

El sondeo ponderado de Dubbo ha pasado por el sondeo ponderado mencionado anteriormente para suavizar el proceso de sondeo ponderado.

El código específico no se analiza, es más complicado. De todos modos, significa esto. Dubbo se refiere al sondeo ponderado suave realizado por Nginx.

Personalmente, creo que esto es similar al primer RandomLoadBalance.

Concatenarlos

Hasta ahora, incluidos los catálogos de servicios, los clústeres y el equilibrio de carga. Creo que todos ya saben para qué se utilizan. Luego están las diferencias y los escenarios aplicables de las clases de implementación predeterminadas de Dubbo. Permítanme hablar de esto en serie. Varios cooperan para completar la función de equilibrio de carga tolerante a fallas del clúster.

Primero mire esta imagen en el sitio web oficial, es muy clara, y luego usaré palabras para explicarla nuevamente.
Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

Primero, cuando se introduce el servicio, se introducen varias llamadas remotas en el directorio, y luego el directorio se encapsula a través del clúster, y la encapsulación proporciona varias funciones de tolerancia a fallos, como FailOver, FailFast, etc., y finalmente se expone a los consumidores es uno. invocador.

Luego, cuando los consumidores llamen, obtendrán la lista de invocadores en el directorio. Por supuesto, serán filtrados por enrutamiento. Después de que se obtengan estos invocadores, loadBalance realizará un balance de carga para seleccionar un invocador y finalmente iniciar la llamada.

Este proceso se inicia realmente dentro del Clúster, por lo que se pueden utilizar varias medidas tolerantes a fallas en caso de un error en el inicio de la llamada.

Al final

Mi hermana me preguntó: Equilibrio de carga tolerante a fallas del clúster Dubbo

En este punto, todo el sistema Dubbo debería ser familiar. Puede mirar hacia atrás en el artículo anterior para consolidarlo y repasarlo nuevamente en su mente. Todo este sistema ha sido establecido en su mente y es básicamente estable.

En el seguimiento de Dubbo, publicaré la última versión de productos secos de la entrevista para terminar. De hecho, el período de escribir dubbo es muy complicado para mí, porque realmente hay poca gente que escribe productos técnicos secos, pero todavía quiero seguir escribiéndolo, diciendo Para ser honesto, no digamos que no le gusta leerlo. Soy muy seco al escribir. A veces es muy difícil ceñirse a él. Pero pienso en ello cuando quiera leerlo en el futuro. Arriba.

No me importa el tiempo eterno, solo me importa tenerlo una vez y amarlo. Soy Ao Bing. Gracias por tu Sanlian. Cuanto más sabes, más no sabes. Nos vemos en el próximo número.

Supongo que te gusta

Origin blog.51cto.com/14689292/2545233
Recomendado
Clasificación