Levá-lo para aprender a análise do código-fonte do design do kernel Nacos (2) Explore o mistério dos projetos de código aberto

Projeto do kernel Nacos

Protocolo de Consistência Nacos

Por que o Nacos precisa de um protocolo de consenso?
O Nacos estabeleceu uma meta no suporte de código aberto para reduzir ao máximo os custos de implantação e operação e manutenção do usuário, para que os usuários precisem apenas de um pacote para iniciar o Nacos rapidamente no modo autônomo ou usar Iniciar Nacos em modo cluster. O Nacos é um componente que precisa armazenar dados, portanto, para atingir esse objetivo, o armazenamento de dados precisa ser implementado dentro do Nacos. Na verdade, não é um grande problema em uma única máquina, e um simples banco de dados relacional embutido é suficiente, mas no modo cluster, é necessário considerar como garantir a consistência dos dados e sincronização de dados entre cada nó. , temos que introduzir o algoritmo Consensus, que garante a consistência dos dados entre os nós por meio de algoritmos.

Por que a Nacos escolheu Raft e Distro
?Por que a Nacos executa o protocolo CP e o protocolo AP em um único cluster? Na verdade, isso começa a partir do cenário Nacos: Nacos é um componente que integra descoberta de registro de serviço e gerenciamento de configuração, portanto, para garantir a consistência dos dados entre os nós do cluster, ele precisa ser dividido em dois aspectos

Do ponto de vista da descoberta de registro de serviço,
o registro de descoberta de serviço é um componente muito importante no sistema de microsserviço atual. Registro de descoberta. Portanto, altos requisitos são apresentados para a disponibilidade do registro de serviço e componentes do centro de descoberta. Em qualquer cenário, é necessário garantir que o registro de serviço e os recursos de descoberta possam fornecer serviços ao mundo exterior o máximo possível. Ao mesmo tempo, o design de descoberta de registro de serviço da Nacos adota a pulsação para completar automaticamente o serviço.O mecanismo de compensação de dados. Se os dados forem perdidos, esse mecanismo pode rapidamente compensar a perda de dados.
Portanto, para atender à disponibilidade do registro de descoberta de serviço, um algoritmo de consenso forte não é adequado aqui, pois é necessário saber se o algoritmo de consenso forte pode fornecer serviços externos, se o número de nós disponíveis no cluster atual não mais da metade dela for atingida, todo o algoritmo “atacará” diretamente, enquanto o algoritmo de consenso final garantirá a disponibilidade dos serviços e garantirá que
os dados entre todos os nós possam ser acordados dentro de um determinado período de tempo. Os itens acima são todos para os serviços não persistentes no registro de descoberta de serviço Nacos (ou seja, o cliente precisa relatar a pulsação para
renovar a instância de serviço). Para o serviço persistente no registro de descoberta de serviço Nacos, porque todos os dados são criados diretamente ao chamar o servidor Nacos, é necessário garantir a forte consistência de dados entre nós por Nacos, portanto, para este tipo de serviço Data, um forte consenso de consenso algoritmo é selecionado para garantir a consistência dos dados.

Do ponto de vista do gerenciamento de configuração,
os dados de configuração são criados e gerenciados diretamente no servidor Nacos. Deve-se garantir que a maioria dos nós tenha salvo esses dados de configuração antes que a configuração seja considerada salva com sucesso, caso contrário, as alterações de configuração serão perdidas. Se isso acontecer, o problema é muito sério. Se uma alteração importante de configuração for liberada e a ação de alteração for perdida, provavelmente causará uma falha grave da rede existente. Portanto, para o gerenciamento dos dados de configuração, é necessário requerem clusters grandes e pequenos no cluster Alguns nós são fortemente consistentes e apenas um algoritmo de consenso forte pode ser usado aqui.

Por que Raft e Distro?
Para o algoritmo de consenso forte, o protocolo Raft é mais usado na produção industrial atual. O protocolo Raft é mais fácil de entender, e existem muitas implementações de algoritmos industriais maduros, como JRaft da Ant Financial. ZAB do Zookeeper, Consul's Raft, braft do Baidu, Apache Ratis; porque Nacos é uma pilha de tecnologia Java, ele só pode ser selecionado entre JRaft, ZAB, Apache Ratis, mas ZAB está fortemente ligado ao Zookeeper, além disso, espero poder trabalhar com Raft A equipe de suporte da biblioteca de algoritmos se comunica a qualquer momento, então JRaft é selecionado.JRaft também é selecionado porque JRaft suporta vários RaftGroups, o que traz a possibilidade de vários fragmentos de dados por trás do Nacos.

O protocolo Distro é um protocolo de consistência eventual desenvolvido pelo Alibaba, e existem muitos protocolos de consistência eventual, como os algoritmos de sincronização de dados em Gossip e Eureka. O algoritmo Distro é baseado nas vantagens dos protocolos Gossip e Eureka e otimizado. Para o Gossip nativo, como o nó que envia a mensagem é selecionado aleatoriamente, é inevitável que a mensagem seja enviada repetidamente para o mesmo nó, o que aumenta a rede A pressão de transmissão também traz carga extra de processamento para os nós de mensagens, e o algoritmo Distro introduz o conceito de servidor autoritativo, cada nó é responsável por uma parte dos dados e sincroniza seus próprios dados com outros nós, reduzindo efetivamente a redundância de mensagens O problema.

Em seguida, revelamos como eles são implementados a partir do código-fonte

Vamos olhar para o código-fonte e primeiro olhar para sua classe e design de interface.A
insira a descrição da imagem aqui
fim de alcançar a reutilização e baixo acoplamento entre os módulos, nacos projeta módulos diferentes.

Vamos ver como os nacos começam a funcionar

A inicialização do Nacos primeiro precisa ler o arquivo de configuração, então ele é chamado desta classe

/**
 * 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);
    }

Todos os nacos registro, assinatura e
insira a descrição da imagem aqui
código de inicialização de outras interfaces

 /**
     * 主要方法实现
     * @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));
    }

O próximo passo é registrar cada instância de serviço

@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);
    }

Quando o serviço ficar offline, a instância será destruída e o pool de threads recém-iniciado será destruído.

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

Consulte o processo de destruição específico

O design inteligente do pool de threads da análise de código-fonte Nacos (1) pode ser adicionado ao seu próprio projeto

Este artigo começará aqui, e o próximo artigo compartilhará com você como o nacos implementa um protocolo de consenso distribuído.

Todos devem se lembrar de curtir, se inscrever e seguir

Atualize o próximo artigo, você é a primeira vez que aprende

Seu apoio é a força motriz para eu continuar a criar! ! !

Acho que você gosta

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