Diagrama + código fuente para explicar la actualización de la lista de servicios de Ribbon

¡Acostúmbrate a escribir juntos! Este es el día 13 de mi participación en el "Desafío de actualización de abril del nuevo plan diario de Nuggets", haga clic para ver los detalles del evento

Diagrama + código fuente para explicar la actualización de la lista de servicios de Ribbon

La diligencia es el factor decisivo para el genio - Guo Moruo

Artículos relacionados
Ilustración + Código fuente Explicación de la cinta Cómo obtener el Centro de registro Ejemplo
Ilustración + Código fuente Explicación de los principios de la cinta

Equilibrador de carga de servicio dinámico DynamicServerListLoadBalancer

    Hay un método restOfInit en este balanceador de carga.Este método implica extraer la lista de servicios del registro y extraer o monitorear los cambios de la lista de actualización, y luego configurarlo en el balanceador de carga y proporcionarlo al tiempo de ejecución de la solicitud. una selección de servicios

public DynamicServerListLoadBalancer(IClientConfig clientConfig, IRule rule,
    IPing ping, ServerList<T> serverList, ServerListFilter<T> filter,
    ServerListUpdater serverListUpdater) {
    super(clientConfig, rule, ping);
    this.serverListImpl = serverList;
    this.filter = filter;
    this.serverListUpdater = serverListUpdater;
    if (filter instanceof AbstractServerListFilter) {
        ((AbstractServerListFilter) filter).
            setLoadBalancerStats(getLoadBalancerStats());
    }
    // 核心方法,其他的方法先不细看
    restOfInit(clientConfig);
}
复制代码

    En este método, enableAndInitLearnNewServersFeature es un método central que se utiliza para realizar una lista de cambios de servicio de extracción o supervisión específica.

    void restOfInit(IClientConfig clientConfig) {
        boolean primeConnection = this.isEnablePrimingConnections();
        // turn this off to avoid duplicated asynchronous priming done in BaseLoadBalancer.setServerList()
        this.setEnablePrimingConnections(false);
        enableAndInitLearnNewServersFeature();

        updateListOfServers();
        if (primeConnection && this.getPrimeConnections() != null) {
            this.getPrimeConnections()
                    .primeConnections(getReachableServers());
        }
        this.setEnablePrimingConnections(primeConnection);
        LOGGER.info("DynamicServerListLoadBalancer for client {} initialized: {}", clientConfig.getClientName(), this.toString());
    }
复制代码

Operación de cambio de lista de servicios enableAndInitLearnNewServersFeature

    Habilitar la operación de notificación de actualización de cambio de lista de servicios

public void enableAndInitLearnNewServersFeature() {
    // 服务列表更新器开启 updateAction 更新操作
    serverListUpdater.start(updateAction);
}
复制代码
protected final ServerListUpdater.UpdateAction updateAction = 
        new ServerListUpdater.UpdateAction() {
    @Override
    public void doUpdate() {
        // 这个就是上面讲解的服务实例拉取操作
        updateListOfServers();
    }
};
复制代码

Política de cambio de lista de servicios

Estrategia de extracción cronometrada

    El método serverListUpdater.start tiene dos estrategias de implementación, una es la operación de notificación de servicio eureka, la otra es la operación de cambio de servicio de extracción activa, el valor predeterminado es la estrategia de servicio de actualización PollingServerListUpdater [la estrategia PollingServerListUpdater se ha creado en RibbonClientConfiguration] como se muestra a continuación
imagen.png

@Bean
@ConditionalOnMissingBean
public ServerListUpdater ribbonServerListUpdater(IClientConfig config) {
    return new PollingServerListUpdater(config);
}

复制代码

imagen.png

Extraiga periódicamente la lista de servicios actualizada PollingServerListUpdater

    30s para extraer la lista de servicios una vez para ver si la lista de servicios ha cambiado

private static long LISTOFSERVERS_CACHE_UPDATE_DELAY = 1000; // msecs;
// 30s 去拉取一次
private static int LISTOFSERVERS_CACHE_REPEAT_INTERVAL = 30 * 1000; // msecs;


public PollingServerListUpdater() {
    this(LISTOFSERVERS_CACHE_UPDATE_DELAY, LISTOFSERVERS_CACHE_REPEAT_INTERVAL);
}
public PollingServerListUpdater(final long initialDelayMs, final long refreshIntervalMs) {
    this.initialDelayMs = initialDelayMs;
    this.refreshIntervalMs = refreshIntervalMs;
}
复制代码

PollingServerListUpdater#start 方法

    Se creó un programador de subprocesos para ejecutar la tarea wrapperRunnable con un retraso y una frecuencia fijos.

@Override
public synchronized void start(final UpdateAction updateAction) {
    // 创建一个线程
    final Runnable wrapperRunnable = new Runnable() {
        @Override
        public void run() {
            if (!isActive.get()) {
                if (scheduledFuture != null) {
                    scheduledFuture.cancel(true);
                }
                return;
            }
            try {
                updateAction.doUpdate();
                lastUpdated = System.currentTimeMillis();
            } catch (Exception e) {
                logger.warn("Failed one update cycle", e);
            }
        }
    };
    // 线程调度器调度 wrapperRunnable 任务
    scheduledFuture = getRefreshExecutor().scheduleWithFixedDelay(
            wrapperRunnable,
            initialDelayMs,
            refreshIntervalMs,
            TimeUnit.MILLISECONDS
    );

}
复制代码

updateAction.doUpdate() actualiza periódicamente la lista de servicios

    updateAction es la UpdateAction pasada en el método enableAndInitLearnNewServersFeature() anterior De hecho, es para llamar al método updateListOfServers() regularmente para actualizar la lista de servicios.

protected final ServerListUpdater.UpdateAction updateAction = new ServerListUpdater.UpdateAction() {
    @Override
    public void doUpdate() {
        updateListOfServers();
    }
};
复制代码

Estrategia de monitoreo del servicio

Actualizador de la lista del servicio de notificaciones de Eureka EurekaNotificationServerListUpdater

// eureka事件监听器
private volatile EurekaEventListener updateListener;
// eureka 客户端
private volatile EurekaClient eurekaClient;

public EurekaNotificationServerListUpdater() {
    this(new LegacyEurekaClientProvider());
}

public EurekaNotificationServerListUpdater(final Provider<EurekaClient> 
                                eurekaClientProvider) {
    this(eurekaClientProvider, getDefaultRefreshExecutor());
}
// 构造 eureka通知服务列表监听器
public EurekaNotificationServerListUpdater(final Provider<EurekaClient>
            eurekaClientProvider, ExecutorService refreshExecutor) {
    this.eurekaClientProvider = eurekaClientProvider;
    this.refreshExecutor = refreshExecutor;
}
复制代码

EurekaNotificationServerListUpdater#start 方法

public synchronized void start(final UpdateAction updateAction) {
if (isActive.compareAndSet(false, true)) {
    // 创建了一个eureka事件监听器
    this.updateListener = new EurekaEventListener() {
        @Override
    public void onEvent(EurekaEvent event) {
        // 缓存刷新事件
        if (event instanceof CacheRefreshedEvent) {
            if (!refreshExecutor.isShutdown()) {
                refreshExecutor.submit(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            // 进行服务列表更新
                            updateAction.doUpdate();
                            lastUpdated.set(System.currentTimeMillis());
                        } catch (Exception e) {
                            logger.warn("Failed to update serverList", e);
                        } finally {
                            updateQueued.set(false);
                        }
                    }
                });
            }
            else {
                stop();
            }
        }
    }
    };
    if (eurekaClient == null) {
        // 获取 eureka 客户端 
        eurekaClient = eurekaClientProvider.get();
    }
    if (eurekaClient != null) {
        // 注册监听器
        eurekaClient.registerEventListener(updateListener);
    } 
}
复制代码

updateAction.doUpdate() Este método es el mismo que el seguimiento anterior

resumen

  1. Dos formas de actualizar la lista de servicios
  2. Una es extraer y actualizar periódicamente la operación de la lista.
  3. Uno es el evento de notificación de actualización de caché eureka para actualizar la lista de servicios

Supongo que te gusta

Origin juejin.im/post/7085892529186406430
Recomendado
Clasificación