[Arquitetura do sistema] Fale sobre a arquitetura e os princípios do middleware de mensagens de código aberto

Falando em middleware de mensagem, os calçados infantis na Internet devem subconscientemente ser de alta simultaneidade, planejamento de io de alto desempenho, etc. vêm à mente, mas para aplicativos, pode ser mais do que simples desempenho, especialmente para transações. Para plataformas de negócios que lidam com finanças.

Ok, deixe-me apresentar a você na plataforma de negociação financeira, quais cenários exigem o uso de middleware de mensagem? Por que usar? Como projetar uma nuvem privada de middleware para tornar o desenvolvimento mais agradável? (Tendo em vista as diferentes habilidades linguísticas de diferentes alunos, falarei apenas sobre os princípios e mecanismos de design aqui. Este artigo envolverá produtos de código aberto populares no mercado, como activemq, rabbitmq, kafka, metaq, etc.)

A função do middleware de mensagem é usar como portadora para simultaneidade assíncrona. Além disso, ainda precisa garantir muitos recursos na arquitetura, alta disponibilidade, alta simultaneidade, escalabilidade, confiabilidade, integridade, ordem de garantia, etc., apenas Isso já causou dores de cabeça para vários designers; também existem alguns requisitos anormais, como consumo lento, não repetibilidade, etc. O custo do design é bastante alto, então não acredite cegamente em especialistas em código aberto. Para muitos mecanismos, quase Deve ser reconstruído; não é tão simples construir uma nuvem privada universal amigável que atenda a todas as empresas.

Se um sistema de pagamento precisa processar bilhões de pedidos de negócios todos os dias, então a capacidade de processamento do middleware de mensagem deve chegar a pelo menos quase 10 bilhões, porque muitos sistemas dependem dos recursos de clustering do middleware e devem garantir que não haja nenhum erro, então, vamos Vamos analisar como o middleware faz isso a partir de alguns aspectos da arquitetura.

Alta disponibilidade

Alta disponibilidade é um tópico eterno. Essa também é uma medida para saber se ela é confiável no mundo financeiro. Você deve saber que os arquitetos do setor financeiro encontrarão maneiras de evitar a perda de dados, até mesmo uma parte dos dados, mas, na verdade, essa coisa Em teoria, depende do personagem. . . Este não é um tolo.

Por exemplo, na arquitetura de dados da Internet, pelo menos três cópias de um dado são chamadas de altas garantias, mas, na verdade, o data center belga do Google foi permanentemente perdido após queda de raios em 8,13, 0,000001% do data center, menos de 0,05 % Dos discos não puderam ser reparados. O que eu quero dizer aqui é que a hora e o lugar certos são muito importantes. Não há nada impossível em condições extremas. Deve haver vulnerabilidades de arquitetura. Vamos dar uma olhada na prática geral de alta disponibilidade mq: a
imagem a seguir é ativemq HA Programa:
[Arquitetura do sistema] Fale sobre a arquitetura e os princípios do middleware de mensagens de código aberto

A HA da Activemq é gerenciada por failover mestre / escravo, onde a comutação mestre-escravo pode ser alternada de várias maneiras:
1: Um bloqueio compartilhado é executado por meio de um nfs ou outro dispositivo de disco compartilhado, e o mestre é marcado pela propriedade do bloqueio de arquivo compartilhado Quando m desliga, o escravo correspondente irá ocupar o shared_lock e converter para mestre

2: O gerenciamento de cluster por meio do zookeeper é mais comum. A
figura a seguir não é apresentada aqui . O esquema HA do metaq é
[Arquitetura do sistema] Fale sobre a arquitetura e os princípios do middleware de mensagens de código aberto
como mostrado na figura acima. É exatamente o mesmo e também é o nó mestre-escravo do gerenciamento do corretor por meio do zk.

Claro, este é apenas um dos mecanismos de failover, que só pode garantir que a mensagem será transferida para o escravo quando o corretor travar, mas não pode garantir a perda da mensagem no processo intermediário

Quando a mensagem flui através do broker, é provável que seja causado por tempo de inatividade ou outras falhas de hardware, que podem fazer com que a mensagem seja perdida.Neste momento, um meio de armazenamento relevante é necessário para garantir a mensagem.

Em seguida, tomamos o mecanismo de armazenamento de Kafka como referência. Devemos saber que a dependência do middleware de mensagem no armazenamento não requer apenas velocidade rápida, mas também requer um custo muito baixo de requisitos de IO. Kafka projetou um conjunto de mecanismos de armazenamento para atender aos requisitos acima, que são simples aqui. introduzir.

Primeiro, o tópico em kafka é dividido em várias partições sob implantação distribuída. A partição é equivalente a um carregamento de mensagens e, em seguida, o roteamento por várias máquinas. Por exemplo: um tópico, debit_account_msg será dividido em debit_account_msg_0, debit_account_msg_1 , debit_account_msg_2. . . Esperando por N partições, cada partição irá gerar um diretório localmente, como / debit_account_msg / topic

O arquivo dentro será dividido em vários segmentos, cada segmento definirá um tamanho, como 500 MB de um segmento, um arquivo é dividido em duas partes: índice e log
00000000000000000.index
00000000000000000.log
00000000000065535.index
00000000000065535.log
onde o número representa o valor de msgId O ponto de partida do índice, a estrutura de dados correspondente é a seguinte:
[Arquitetura do sistema] Fale sobre a arquitetura e os princípios do middleware de mensagens de código aberto
1,0 representa a mensagem com msgId sendo 1 e 0 representa o deslocamento neste arquivo.Depois de ler este arquivo, encontre o arquivo de log do segmento correspondente e leia-o. Informações de msg correspondentes, as informações correspondentes são um corpo de mensagem de formato fixo:
[Arquitetura do sistema] Fale sobre a arquitetura e os princípios do middleware de mensagens de código aberto
Obviamente, a aplicação simples deste mecanismo definitivamente não é suficiente para atender a alta IO simultânea. Primeiro, pesquise o binário do segmentfile, em seguida, encontre os dados correspondentes por meio do deslocamento, depois leia msgsize e, em seguida, Ler o corpo do jornal requer pelo menos 4 discos io vezes, o que é caro, mas a leitura sequencial é usada para puxar, que basicamente tem pouco efeito.

Além da consulta mencionada acima. Na verdade, antes de gravar no disco, todas as leituras e gravações são realizadas no pagecache do sistema operacional e, em seguida, o disco rígido é liberado (estratégia LRU) periodicamente por meio de threads assíncronos, mas na verdade, esse risco é muito grande, porque uma vez que o sistema operacional caia, ele causará Perda de dados, especialmente no caso de consumo lento e muito acúmulo de dados, mas o irmão de Kafka, metaq, fez muitas transformações nesta área, e o mecanismo de replicação (usado por Ali) é realizado nesses arquivos de partição, portanto, neste nível Não importa como o raio caia, as chances de perder mensagens serão menores.Claro, isso não exclui o que acontece quando o cabo óptico na sala de host é desenterrado.

Tendo dito tudo isso, parece ser perfeito e bonito, mas na verdade os custos de operação e manutenção parecem ser enormes. Como esses são todos arquivos, uma vez que um problema ocorre, será bastante complicado lidar com ele manualmente, e está em uma máquina, o que requer custos de operação e manutenção relativamente grandes para fazer algumas especificações de operação e manutenção e recursos de chamada de API.

Portanto, nesta área, podemos armazenar dados em alguns nosql, como mongoDB. Claro, mysql também é possível, mas a capacidade io e nosqldb não estão no mesmo nível, a menos que tenhamos um mecanismo de processamento de transação forte. Li é bastante rígido com esse requisito. Por exemplo, metaq é usado atrás do Alipay, porque o middleware anterior tbnotify é muito passivo ao lidar com consumo lento, e metaq terá uma grande vantagem nesta área.Por favor, ouça a decomposição mais tarde.

Alta simultaneidade

No início, a maioria dos engenheiros usava mq para resolver os problemas de desempenho e de assincronização. Na verdade, para o mesmo ponto, um agendamento io não exige tantos recursos. Vejamos alguns dos altos em mq. Simultaneidade, primeiro introduza o histórico de vários middlewares bem conhecidos:

O Activemq era uma solução especializada de nível empresarial na época. Cumpria com a especificação jms do jee. Na verdade, o desempenho ainda era bom, mas era um coelho segurando uma melancia quando foi puxado para a Internet.

Rabbitmq é escrito em linguagem erlang, está em conformidade com as especificações do protocolo AMQP e tem uma natureza multiplataforma. O modo de transferência deve ser mais rico e distribuído

Rocketmq (a versão mais recente do metaq3.0 agora, kafka também é o predecessor do metaq, originalmente o sistema de mensagens de log aberto por linkedIn), o metaq basicamente escreve os princípios e mecanismos do kafka em java. Após muitas modificações, ele suporta transações. A velocidade de desenvolvimento é muito rápida e existem comunidades muito boas em Ali e na China para fazer essa manutenção.

Comparação de desempenho, aqui estão alguns dados da Internet, apenas para referência:
[Arquitetura do sistema] Fale sobre a arquitetura e os princípios do middleware de mensagens de código aberto

Para ser honesto, em termos desses níveis de dados, a diferença não é tão exagerada, mas podemos analisar alguns pontos em comum, onde estão essas principais diferenças de desempenho?
Rocketmq é o sucessor do metaq. Além de melhorias em alguns novos recursos e mecanismos, os princípios de desempenho são semelhantes. Aqui estão alguns destaques desse alto desempenho:

  • O consumo de rocketmq usa principalmente o mecanismo de puxar. Portanto, para o corretor, muitos recursos de consumo não precisam ser implementados no corretor. Você só precisa extrair os dados relevantes por meio do consumidor. E, como activemq e rabbitmq, todos eles usam os mais antigos. A maneira de permitir que o corretor despache a mensagem, é claro, alguns dos métodos de entrega padrão de jms ou amqp

  • O armazenamento de arquivos é armazenado sequencialmente, então, quando você puxa mensagens, você só precisa chamar os dados do segmento, e o consumidor consome informações ao máximo ao fazer o consumo, é improvável que gere um backlog e você pode definir io Algoritmos de agendamento, como o modo noop, podem melhorar o desempenho de algumas leituras sequenciais.

  • Use pagecache para acessar os dados no cache do sistema operacional para atingir um consumo quente

  • IO de disco de lote e IO de rede da Metaq, tente fazer os dados rodarem em um io, as mensagens são todas em lotes, de modo que o agendamento de io não precise consumir muitos recursos

  • Transmissão NIO, conforme mostrado na figura abaixo, esta é uma arquitetura do metaq original. Inicialmente, o metaq usou alguns frameworks NIO de alto desempenho integrados com gecko e notificação-remoting dentro do Taobao para distribuir mensagens
    [Arquitetura do sistema] Fale sobre a arquitetura e os princípios do middleware de mensagens de código aberto
  • O peso leve da fila de consumo, devemos saber que nossa capacidade de mensagem é obtida através da fila

Observe a figura a seguir:
[Arquitetura do sistema] Fale sobre a arquitetura e os princípios do middleware de mensagens de código aberto
Metaq adiciona uma fila lógica à fila física para consumo. Os dados do disco correspondentes à fila são serializados. A adição da fila não aumenta a carga do disco iowait. A gravação pode ser sequencial, mas durante a leitura Ainda precisa usar leitura aleatória, primeiro fila lógica, depois ler o disco, então o pagecache é muito importante, tente aumentar a memória, essa alocação será totalmente utilizada.

Na verdade, atingir o acima pode basicamente garantir que nosso desempenho esteja em um nível relativamente alto; mas às vezes o desempenho não é o mais importante, o mais importante é fazer o melhor equilíbrio com outros recursos arquitetônicos, afinal, existem Outros mecanismos devem ser satisfeitos. Porque basicamente os três problemas mais difíceis na indústria: alta simultaneidade, alta disponibilidade e consistência conflitam entre si.

Escalável

Esta é uma pergunta antiquada. Para sistemas gerais ou middleware, pode ser melhor estendida, mas na área de middleware de mensagem, sempre foi um incômodo. Por quê?

Deixe-me falar sobre as limitações da expansão da activemq, porque a expansão da activemq requer natureza comercial. Como um corretor, você deve primeiro saber a origem e o destino, mas se essas mensagens forem transmissão distribuída, será complicado. Vamos dar uma olhada em activemq. Como brincar com a carga.
[Arquitetura do sistema] Fale sobre a arquitetura e os princípios do middleware de mensagens de código aberto
Presumimos que o produtor envia mensagens topicA. Se todos os consumidores estiverem conectados a cada corretor em circunstâncias normais, o que é interessante? Se houver uma mensagem do produtor no corretor, ela pode ser transferida para o corretor correspondente No consumidor.
Mas se não houver um mensageiro correspondente conectado a ele no broker2, o que devemos fazer neste caso? Como há muitos nós no sistema de aplicação (produtor) e sistema dependente (consumidor) do mesmo tópico, como expandir a capacidade? O Activemq pode fazer a parte normal da figura acima, mas é bastante problemático alterar a configuração correspondente do produtor, corretor e consumidor.
Claro, activemq também pode fazer pesquisa dinâmica por multicast (algumas pessoas também mencionaram o uso de lvs ou f5 para carregar, mas existem grandes problemas para os consumidores, e esta configuração de carga não tem efeito substancial na distribuição de tópicos) No entanto, ainda haverá o problema que mencionei. Se o tópico for muito grande, cada corretor precisa se conectar a todos os produtores ou consumidores, caso contrário, a situação que eu disse vai ocorrer. A expansão da Activemq é bastante problemática.

Vamos falar sobre como o metaq faz isso. Olhe para a imagem. O
[Arquitetura do sistema] Fale sobre a arquitetura e os princípios do middleware de mensagens de código aberto
Metaq usa tópicos como partições. Neste nível, só precisamos configurar o número de partições de tópicos, de modo que haja apenas uma partição. O conceito de "negócios" é usado como uma regra de roteamento; geralmente, vários tópicos são configurados em uma máquina corretora e cada tópico geralmente tem apenas uma partição em uma máquina. Se a máquina não for suficiente, ela também pode suportar várias partições. De um modo geral, nós Você pode personalizar a partição obtendo o módulo do id de negócio, apenas obtendo os parâmetros da zona de envio.
[Arquitetura do sistema] Fale sobre a arquitetura e os princípios do middleware de mensagens de código aberto
Os consumidores de metaq também usam o método de carregamento de grupo (esse grupo geralmente é configurado de acordo com os recursos da partição) para extrair mensagens da partição. Se houver muitos consumidores, eles não precisam participar do consumo. Geralmente, esse é o caso online, porque, afinal, o servidor de aplicativos é muito maior do que o servidor de mensagens.
[Arquitetura do sistema] Fale sobre a arquitetura e os princípios do middleware de mensagens de código aberto
Em outro caso, quando há muitas partições, conforme mostrado na figura abaixo, quando
[Arquitetura do sistema] Fale sobre a arquitetura e os princípios do middleware de mensagens de código aberto
a carga depende muito das mensagens principais, os requisitos para o broker do servidor ainda são relativamente altos. Afinal, a quantidade de dependência é relativamente grande. Além disso, se a mensagem tiver características de broadcast, pode ser Maior, portanto, para o corretor, um disco rígido de io elevado e grande memória são necessários para o pagecache, e os cálculos reais necessários não precisam ser muito grandes
[Arquitetura do sistema] Fale sobre a arquitetura e os princípios do middleware de mensagens de código aberto

confiabilidade

Confiabilidade é um recurso importante do middleware de mensagem. Vamos ver como o mq transfere essas mensagens. Vamos primeiro tomar activemq como referência. Ele é baseado no mecanismo push & push.

Como garantir que todas as mensagens enviadas sejam consumidas? Depois que o produtor Activemq envia uma mensagem, ele precisa receber um ack do corretor para confirmar o recebimento.A mesma garantia também é válida para o corretor para o consumidor.

O mecanismo do Metaq é o mesmo, mas o corretor chega ao consumidor por meio de um método pull, portanto, sua garantia de chegada depende da capacidade do consumidor, mas, em geral, é improvável que o cluster do servidor de aplicativos tenha um efeito de avalanche.

Como garantir a idempotência das mensagens? Atualmente, basicamente nem a Activemq nem a Metaq podem garantir a idempotência das mensagens, o que requer alguns negócios para garantir. Porque assim que o tempo limite do corretor se esgotar, ele tentará novamente. Se você tentar novamente, uma nova mensagem será gerada. É possível que o corretor já tenha recebido a mensagem. Nesse caso, é impossível garantir que a mesma transação comercial gere duas mensagens.

Como garantir a confiabilidade da mensagem? Neste ponto, activemq e metaq têm basicamente o mesmo mecanismo:
Garantia do produtor: depois de produzir dados, eles devem ser persistidos após chegar ao corretor antes de retornar o ACK ao
corretor de origem . Garantia: após receber a mensagem, o servidor metaq a atualiza para o disco rígido regularmente e, em seguida, os dados Todos são replicados para o escravo através de síncrono / assíncrono, para garantir que o consumo não seja afetado após o tempo de inatividade.O
Activemq também é armazenado localmente através do banco de dados ou arquivos para recuperação local.

Garantia do consumidor: O consumidor da mensagem consome a mensagem um por um e só consome a próxima mensagem depois de consumir uma mensagem com sucesso. Se uma mensagem não puder ser consumida (como uma exceção), ela tentará consumi-la novamente (o máximo padrão é 5 vezes). Depois que o número máximo de vezes ainda não puder ser consumido, a mensagem será armazenada no disco local do consumidor e no thread de segundo plano Continue tentando novamente. O thread principal continua a voltar e consome as mensagens subsequentes. Portanto, somente após o MessageListener confirmar que uma mensagem foi consumida com êxito, o meta consumidor continuará a consumir outra mensagem. Isso garante um consumo confiável de mensagens.

consistência

A consistência do mq discutimos dois cenários:
1: para garantir que a mensagem não seja enviada / consumida várias vezes

2: Transações de garantia
. Alguns dos mqs descritos acima não podem garantir consistência. Por que não garantir? O custo é relativamente alto. Só podemos dizer que isso pode ser garantido modificando o código-fonte, e o esquema é relativamente não muito complicado, mas a sobrecarga adicional é relativamente grande, como garantir um determinado período de tempo por meio de um cluster de cache adicional. Repetibilidade, acredito que deve haver algum mq com esta função mais tarde.

Activemq suporta dois tipos de transações, uma é a transação JMS e o outro é a transação distribuída XA. Se você trouxer uma transação, um transactionId será gerado para o corretor durante a interação. O corretor implementa algumas TMs para alocar o processamento da transação. O Metaq também oferece suporte a transações locais e XA, em conformidade com o padrão JTA. As garantias de transação de activemq e metaq são todas feitas através do método de redo log, que é basicamente o mesmo.

A transação distribuída aqui só é garantida após a fase do broker.A mensagem preparada será armazenada em um arquivo local antes da confirmação do broker e a mensagem será gravada na fila na fase de confirmação e, finalmente, a confirmação de duas fases é realizada através do TM.

resumo

Por exemplo, a empresa também tem algum middleware de mensagem com muito bom desempenho. Espero que possa ser de código aberto e usado por mais pessoas no futuro. Para alguns middleware de mensagens populares, podemos personalizar diferentes arquiteturas para diferentes aplicativos, diferentes custos e diferentes desenvolvimentos.Claro, essas arquiteturas devem ser consideradas em muitos aspectos.

Leitura recomendada:

Cuidadosamente organizado | O catálogo de artigos no segundo semestre de 2017.
Soluções viáveis ​​para forte consistência entre o cache e o banco de dados.
O buffer de processo do usuário e o buffer de kernel
introduzem programação dinâmica por meio de histórias de minas de ouro (parte 1)

Foco no compartilhamento de resumo de conhecimento de pilha de tecnologia de fundo de servidor

Bem-vindo a prestar atenção à comunicação e ao progresso comum

[Arquitetura do sistema] Fale sobre a arquitetura e os princípios do middleware de mensagens de código aberto

Codificação

Os criadores de códigos têm a maneira certa de fornecer artigos técnicos fáceis de entender para tornar a tecnologia mais fácil!

Acho que você gosta

Origin blog.51cto.com/15006953/2552096
Recomendado
Clasificación