Dubbo learning (ocho) equilibrio de carga

Resumen

En la última sección, cuando seleccionamos el clúster, se seleccionaron el invocador final y el método de selección de equilibrio de carga. Veamos primero el código diseñado para el equilibrio de carga en la sección anterior, la clase AbstractClusterInvoker:

   El Invoker privado <T> doSelect (LoadBalance loadbalance, Invocación invocación, 
                                List <Invoker <T>> invocadores, List <Invoker <T>> seleccionado) lanza RpcException { 

        if (CollectionUtils.isEmpty (invocadores)) { 
            return null; 
        } 
        if (invokers.size () == 1) { 
            return invokers.get (0); 
        } 

        // 调用 loadbalance 的 select 方法
        Invoker <T> invoker = loadbalance.select (invocadores, getUrl (), invocación); 

        ... 
    }     

Aquí están las ventajas y desventajas de varios modos de equilibrio de carga.

1297993-20200303161933558-267203461.png

Analicemos varios procesos de implementación de equilibrio de carga.

Análisis de clase padre AbstractLoadBalance

public abstract class AbstractLoadBalance implementa LoadBalance { 


    / ** 
     * Calcule el peso de acuerdo con la proporción de tiempo de actividad del tiempo de calentamiento 
     * el nuevo peso estará dentro de 1 (inclusive) al peso (inclusive) 
     * 
     * warmup: 预热 时间
     * 
     * @param uptime el tiempo de actividad en milisegundos 
     * @param warmup el tiempo de calentamiento en milisegundos 
     * @param pondera el peso de un invocador 
     * @return weight que tiene en cuenta el calentamiento 
     * / 
    static int CalculateWarmupWeight (int uptime, int warmup, int weight) { 
        int ww = (int) (tiempo de actividad / ((flotación) calentamiento / peso)); 
        volver ww <1? 1: (Math.min (ww, peso));
    } 
 
    @Override
    public <T> Invoker <T> select (List <Invoker <T>> invocadores, URL URL, invocación de invocación) { 
        if (CollectionUtils.isEmpty (invocadores)) { 
            return null; 
        } 
        if (invokers.size () == 1) { 
            return invokers.get (0); 
        } 
        return doSelect (invocadores, url, invocación); 
    } 

    resumen protegido <T> Invoker <T> doSelect (List <Invoker <T>> invocadores, URL url, invocación de invocación); 


    / ** 
     * Obtenga el peso de la invocación del invocador que tiene en cuenta el tiempo de calentamiento 
     * si el tiempo de actividad está dentro del tiempo de calentamiento,
     * Al calcular el peso aquí, el núcleo es la proporción de tiempo de actividad / tiempo de calentamiento. Se puede saber que cuando comienza a comenzar, cuanto menor es la proporción de tiempo de actividad es menor que el peso es menor 
     * Cuando el inicio es largo, la proporción es mayor y el peso es naturalmente mayor. . 
     * 
     * @param invocador el invocador 
     * @param invocación la invocación de este invocador 
     * @return weight 
     * / 
    int getWeight (Invoker <?> invocador, invocación de invocación) { 
        int weight; 
        URL url = invoker.getUrl (); 
        // Multiple escenario de registro, equilibrio de carga entre varios registros. 
        if (REGISTRY_SERVICE_REFERENCE_PATH.equals (url.getServiceInterface ())) { 
            weight = url.getParameter (REGISTRY_KEY + "." + WEIGHT_KEY, DEFAULT_WEIGHT); 
        } else {
            peso = url.getMethodParameter (invocation.getMethodName (), WEIGHT_KEY, DEFAULT_WEIGHT); 
            if (peso> 0) { 
                marca de tiempo larga = invoker.getUrl (). getParameter (TIMESTAMP_KEY, 0L); 
                if (marca de tiempo> 0L) { 
                    tiempo de actividad largo = System.currentTimeMillis () - marca de tiempo; 
                    if (tiempo de actividad <0) { 
                        return 1; 
                    } 
                    // 默认 的 预热 时间 是 10 分钟
                    int warmup = invoker.getUrl (). GetParameter (WARMUP_KEY, DEFAULT_WARMUP); 
                    if (tiempo de actividad> 0 && tiempo de actividad <calentamiento) { 
                } 
            } 
                        weight = CalculateWarmupWeight ((int) uptime, warmup, weight);
                    }
        } 
        return Math.max (peso, 0); 
    } 
}

RandomLoadBalance

    @Oversión 
    protegida <T> Invoker <T> doSelect (List <Invoker <T>> invocadores, URL URL, invocación de invocación) { 
        // Número de invocadores 
        int length = invokers.size (); 
        // ¿Cada invocador tiene el mismo peso? 
        booleano sameWeight = verdadero; 
        // el peso de cada invocador 
        int [] weights = new int [length]; 
        // el peso del primer invocador 
        int firstWeight = getWeight (invokers.get (0), invocation); 
        pesos [0] = firstWeight; 
        // La suma de pesos 
        int totalWeight = firstWeight; 
        for (int i = 1; i <length; i ++) {  
            int weight = getWeight (invocadores.get (i), invocación);
            // guardar para uso posterior
            pesos [i] = peso; 
            // Suma 
            totalWeight + = weight; 
            if (sameWeight && weight! = firstWeight) { 
                sameWeight = false; 
            } 
        } 
        if (totalWeight> 0 &&! sameWeight) { 
            // If (no todos los invocadores tienen el mismo peso y al menos el peso de un invocador> 0), seleccione aleatoriamente según totalWeight. 
            int offset = ThreadLocalRandom.current (). nextInt (totalWeight); 
            // Devuelve un invocador basado en el valor aleatorio.  
            / / El bucle resta el peso del proveedor de servicios del número de compensación. Cuando la compensación es menor que 0, se devuelve el Invoker correspondiente.
            // 举例 说明 一下 , 我们 有 servidores = [A, B, C] , pesos = [5, 3, 2] , offset = 7。
            // 第 一次 循环 , offset - 5 = 2> 0 , 即 offset> 5 ,
            // indica que no caerá en el intervalo correspondiente al servidor A. 
            // El segundo ciclo, offset-3 = -1 <0, es decir 5 <offset <8, 
            // indica que caerá en el intervalo correspondiente al servidor B 

            para (int i = 0; i <longitud; i ++) { 
                    offset- 
                = weights [i]; 
                if (offset <0) { return invokers.get (i); 
                } 
            } 
        } 
        // Si todos los invocadores tienen el mismo valor de peso o totalWeight = 0, devuelve de manera uniforme. 
        return invokers.get (ThreadLocalRandom .current (). nextInt (length)); 
    }

Resumen

Los otros tipos de análisis ya no son en profundidad, y todos se basan en el algoritmo de equilibrio para obtener un invocador.

Referencias

  • http://dubbo.apache.org/zh-cn/docs/source_code_guide/loadbalance.html

Supongo que te gusta

Origin www.cnblogs.com/Benjious/p/12720952.html
Recomendado
Clasificación