Lo llevará a aprender el análisis del código fuente del diseño del kernel de Nacos (2) Explore el misterio de los proyectos de código abierto

Diseño del kernel de Nacos

Protocolo de consistencia de Nacos

¿Por qué Nacos necesita un protocolo de consenso?
Nacos ha establecido un objetivo en el soporte de código abierto para reducir los costos de implementación y operación y mantenimiento del usuario tanto como sea posible, de modo que los usuarios solo necesiten un paquete para iniciar rápidamente Nacos en modo independiente o usar Start Nacos en modo racimo. Nacos es un componente que necesita almacenar datos, por lo tanto, para lograr este objetivo, el almacenamiento de datos debe implementarse dentro de Nacos. De hecho, no es un gran problema en una sola máquina, y una base de datos relacional embebida simple es suficiente, pero en el modo de clúster, es necesario considerar cómo garantizar la coherencia de datos y la sincronización de datos entre cada nodo. , tenemos que introducir el algoritmo Consensus, que asegura la consistencia de los datos entre los nodos a través de algoritmos.

¿Por qué Nacos eligió Raft y Distro
?¿Por qué Nacos ejecuta tanto el protocolo CP como el protocolo AP en un solo clúster? En realidad, esto comienza con el escenario de Nacos: Nacos es un componente que integra el descubrimiento de registro de servicios y la gestión de configuración. Por lo tanto, para garantizar la coherencia de datos entre los nodos del clúster, debe dividirse en dos aspectos.

Desde la perspectiva del descubrimiento de registros de servicios,
el registro de descubrimiento de servicios es un componente muy importante en el sistema de microservicios actual. La información de instancia de que los servicios pueden percibir el servicio actual de los servicios de los demás y normalmente pueden proporcionar servicios debe obtenerse del servicio. Registro de descubrimiento. Por lo tanto, se presentan requisitos altos para la disponibilidad de los componentes del centro de registro y descubrimiento del servicio. En cualquier escenario, es necesario garantizar que las capacidades de registro y descubrimiento del servicio puedan proporcionar servicios al mundo exterior tanto como sea posible. Al mismo tiempo, el diseño de descubrimiento de registro de servicio de Nacos adopta el latido del corazón para completar automáticamente el servicio.El mecanismo de compensación de datos. Si se pierden datos, este mecanismo puede compensar rápidamente la pérdida de datos.
Por lo tanto, para cumplir con la disponibilidad del registro de descubrimiento de servicios, un algoritmo de consenso de consenso fuerte no es adecuado aquí, porque se requiere si el algoritmo de consenso fuerte puede proporcionar servicios externos, si la cantidad de nodos disponibles en el clúster actual no lo hace. Si se alcanza más de la mitad, todo el algoritmo "atacará" directamente, mientras que el algoritmo de consenso final garantizará la disponibilidad de los servicios y asegurará que
los datos entre todos los nodos se puedan acordar dentro de un cierto período de tiempo. Todo lo anterior es para los servicios no persistentes en el registro de detección de servicios de Nacos (es decir, el cliente debe informar el latido para
renovar la instancia del servicio). Para el servicio persistente en el registro de detección de servicios de Nacos, debido a que todos los datos se crean directamente llamando al servidor de Nacos, es necesario garantizar la sólida consistencia de los datos entre los nodos por parte de Nacos, por lo que para este tipo de datos de servicio, un consenso de consenso fuerte El algoritmo se selecciona para garantizar la consistencia de los datos.

Desde la perspectiva de la gestión de la configuración,
los datos de configuración se crean y gestionan directamente en el servidor Nacos. Debe asegurarse de que la mayoría de los nodos hayan guardado estos datos de configuración antes de que se considere que la configuración se ha guardado correctamente, de lo contrario, los cambios de configuración se perderán. Si Si esto sucede, el problema es muy grave, si se libera un cambio de configuración importante y se pierde la acción de cambio, lo más probable es que provoque una falla grave en la red existente, por lo que para la gestión de los datos de configuración es necesario requieren clústeres grandes y pequeños en el clúster.Algunos nodos son muy consistentes, y aquí solo se puede usar un algoritmo de consenso de consenso fuerte.

¿Por qué Raft y Distro?
Para el algoritmo de consenso fuerte, el protocolo Raft es el más utilizado en la producción industrial actual. El protocolo Raft es más fácil de entender y hay muchas implementaciones de algoritmos industriales maduros, como JRaft de Ant Financial. Zookeeper's ZAB, Consul's Raft, braft de Baidu, Apache Ratis; debido a que Nacos es una pila de tecnología Java, solo se puede seleccionar de JRaft, ZAB, Apache Ratis, pero ZAB está fuertemente ligado a Zookeeper, además espero poder trabajar con Raft El equipo de soporte de la biblioteca de algoritmos se comunica en cualquier momento, por lo que se selecciona JRaft.JRaft también se selecciona porque JRaft admite múltiples RaftGroups, lo que brinda la posibilidad de fragmentación de datos múltiples detrás de Nacos.

El protocolo Distro es un protocolo de coherencia final desarrollado por Alibaba, y existen muchos protocolos de coherencia final, como los algoritmos de sincronización de datos en Gossip y Eureka. El algoritmo Distro se basa en las ventajas de los protocolos Gossip y Eureka y está optimizado.Para el Gossip nativo, dado que el nodo que envía el mensaje se selecciona aleatoriamente, es inevitable que el mensaje se envíe repetidamente al mismo nodo, lo que aumenta la red La presión de la transmisión también aporta una carga de procesamiento adicional a los nodos de mensajes, y el algoritmo Distro introduce el concepto de servidor autorizado, cada nodo es responsable de una parte de los datos y sincroniza sus propios datos con otros nodos, lo que reduce efectivamente la redundancia de mensajes .El problema.

A continuación, desvelamos cómo se implementan desde el código fuente

Miremos el código fuente y primero veamos su clase y diseño de interfaz
inserte la descripción de la imagen aquí
Para lograr reutilización y bajo acoplamiento entre módulos, nacos diseña diferentes módulos.

A ver como empiezan a funcionar los nacos

El inicio de Nacos primero necesita leer el archivo de configuración, por lo que se llama desde esta clase

/**
 * Nacos Factory.
 *
 * @author Nacos
 */
public class NacosFactory {
    
    
    
    /**
     * Create config service.
     *
     * @param properties init param
     * @return config
     * @throws NacosException Exception
     */
    public static ConfigService createConfigService(Properties properties) throws NacosException {
    
    
        return ConfigFactory.createConfigService(properties);
    }
    
    /**
     * Create config service.
     *
     * @param serverAddr server list
     * @return config
     * @throws NacosException Exception
     */
    public static ConfigService createConfigService(String serverAddr) throws NacosException {
    
    
        return ConfigFactory.createConfigService(serverAddr);
    }
    
    /**
     * Create naming service.
     *
     * @param serverAddr server list
     * @return Naming
     * @throws NacosException Exception
     */
    public static NamingService createNamingService(String serverAddr) throws NacosException {
    
    
        return NamingFactory.createNamingService(serverAddr);
    }
    
    /**
     * Create naming service.
     *
     * @param properties init param
     * @return Naming
     * @throws NacosException Exception
     */
    public static NamingService createNamingService(Properties properties) throws NacosException {
    
    
        return NamingFactory.createNamingService(properties);
    }
    
    /**
     * Create maintain service.
     *
     * @param serverAddr server address
     * @return NamingMaintainService
     * @throws NacosException Exception
     */
    public static NamingMaintainService createMaintainService(String serverAddr) throws NacosException {
    
    
        return NamingMaintainFactory.createMaintainService(serverAddr);
    }
    
    /**
     * Create maintain service.
     *
     * @param properties server address
     * @return NamingMaintainService
     * @throws NacosException Exception
     */
    public static NamingMaintainService createMaintainService(Properties properties) throws NacosException {
    
    
        return NamingMaintainFactory.createMaintainService(properties);
    }


inserte la descripción de la imagen aquí
Todos los códigos de inicialización de registro, suscripción y otras interfaces de nacos

 /**
     * 主要方法实现
     * @param properties
     * @throws NacosException
     */
    private void init(Properties properties) throws NacosException {
    
    
        //校验文件参数
        ValidatorUtils.checkInitParam(properties);
        //初始化命名空间
        this.namespace = InitUtils.initNamespaceForNaming(properties);
        InitUtils.initSerialization();
        initServerAddr(properties);
        InitUtils.initWebRootContext(properties);
        initCacheDir();
        initLogName(properties);
        
        //服务地址代理具体实现,初始化线程池配置
        this.serverProxy = new NamingProxy(this.namespace, this.endpoint, this.serverList, properties);
        //服务心跳
        this.beatReactor = new BeatReactor(this.serverProxy, initClientBeatThreadCount(properties));
        //获取host实现
        this.hostReactor = new HostReactor(this.serverProxy, beatReactor, this.cacheDir, isLoadCacheAtStart(properties),
                isPushEmptyProtect(properties), initPollingThreadCount(properties));
    }

El siguiente paso es registrar cada instancia de servicio

@Override
    public void registerInstance(String serviceName, String groupName, String ip, int port, String clusterName)
            throws NacosException {
    
    

        Instance instance = new Instance();
        instance.setIp(ip);
        instance.setPort(port);
        instance.setWeight(1.0);
        instance.setClusterName(clusterName);

        registerInstance(serviceName, groupName, instance);
    }
@Override
    public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
    
    
        //校验名称是否合法
        NamingUtils.checkInstanceIsLegal(instance);
        //获取namespce对应组
        String groupedServiceName = NamingUtils.getGroupedName(serviceName, groupName);
        //是否是临时实例
        if (instance.isEphemeral()) {
    
    
            //如果是临时实例,增加心跳检测
            BeatInfo beatInfo = beatReactor.buildBeatInfo(groupedServiceName, instance);
            beatReactor.addBeatInfo(groupedServiceName, beatInfo);
        }
        //实例注册
        serverProxy.registerService(groupedServiceName, groupName, instance);
    }

Cuando el servicio se desconecta, la instancia se destruirá y el grupo de subprocesos que se acaba de inicializar también se destruirá.

 @Override
    public void shutDown() throws NacosException {
    
    
        beatReactor.shutdown();
        hostReactor.shutdown();
        serverProxy.shutdown();
    }

Consulte el proceso de destrucción específico

El diseño inteligente del conjunto de subprocesos del análisis del código fuente de Nacos (1) se puede agregar a su propio proyecto

Este artículo comenzará aquí y el próximo artículo compartirá con usted cómo nacos implementa un protocolo de consenso distribuido.

Todos deben recordar dar me gusta, suscribirse y seguir

Actualiza el siguiente artículo, eres la primera vez que aprendes.

¡Tu apoyo es la fuerza que me impulsa a seguir creando! ! !

Supongo que te gusta

Origin blog.csdn.net/weixin_44302240/article/details/123576352
Recomendado
Clasificación