Desenvolva aplicativos altamente disponíveis com o corretor MQTT
A criação de um aplicativo altamente disponível usando o broker MQTT envolve uma consideração cuidadosa dos tipos de sessão, qualidade de serviço (QoS), confirmações de mensagens, processamento paralelo de mensagens, retenção de mensagens e assinaturas compartilhadas. O broker MQTT apresenta um agente e armazenamento de mensagens distribuído na memória que fornece retenção de mensagens e gerenciamento de estado interno com semântica MQTT.
As seções a seguir explicam as configurações e os recursos que contribuem para um aplicativo robusto e sem perda de mensagens e distribuído.
Qualidade de serviço (QoS)
Tanto os editores quanto os assinantes devem usar a QoS-1 para garantir a entrega de mensagens pelo menos uma vez. O broker MQTT armazena e retransmite mensagens até receber uma confirmação (ACK) do destinatário, garantindo que nenhuma mensagem seja perdida durante a transmissão.
Tipo de sessão e sinalizador Clean-Session
Para garantir perda de mensagem zero, defina o sinalizador de início limpo como false ao se conectar ao broker MQTT. Essa configuração informa o broker para manter o estado da sessão para o cliente, preservando assinaturas e mensagens não reconhecidas entre conexões. Se o cliente se desconectar e depois se reconectar, ele retomará de onde parou, recebendo quaisquer mensagens QoS-1 não reconhecidas por meio de uma nova tentativa de entrega de mensagens. Se configurado, o broker MQTT expira a sessão do cliente se o cliente não se reconectar dentro do intervalo de expiração da sessão O padrão é um dia.
Receive-Max em aplicações multithreaded
Os aplicativos multithreaded devem usar receive-max (65.535 max) para processar mensagens em paralelo e aplicar controle de fluxo. Essa configuração otimiza o processamento de mensagens, permitindo que vários threads trabalhem em mensagens simultaneamente e sem que o broker sobrecarregue o aplicativo com uma alta taxa de mensagens acima da capacidade do aplicativo. Cada thread pode processar uma mensagem de forma independente e enviar sua confirmação após a conclusão. Uma prática típica é configurar max-receive proporcionalmente ao número de threads que o aplicativo usa.
Confirmação de mensagens
Quando um aplicativo de assinante envia uma confirmação para uma mensagem QoS-1, ele assume a propriedade da mensagem. Ao receber a confirmação de uma mensagem QoS-1, o broker MQTT para de rastrear a mensagem para esse aplicativo e tópico. A transferência adequada de propriedade garante a preservação da mensagem em caso de problemas de processamento ou falhas no aplicativo. Se um aplicativo quiser protegê-lo de falhas de aplicativo, o aplicativo não deve assumir a propriedade antes de concluir com êxito seu processamento nessa mensagem. Os aplicativos que assinam o broker MQTT devem atrasar a confirmação de mensagens até que o processamento seja concluído até o valor máximo de recebimento com um máximo de 65.535. Isso pode incluir a retransmissão da mensagem, ou uma derivada da mensagem, para o broker MQTT para posterior envio.
Retenção de mensagens e comportamento do broker
O corretor retém mensagens até receber uma confirmação de um assinante, garantindo zero perda de mensagens. Esse comportamento garante que, mesmo que um aplicativo de assinante falhe ou perca a conectividade temporariamente, as mensagens não serão perdidas e poderão ser processadas assim que o aplicativo se reconectar. As mensagens do broker MQTT podem expirar se configuradas pelo Message-Expiry-Interval e um assinante não tiver consumido a mensagem.
Mensagens retidas
As mensagens retidas mantêm o estado temporário do aplicativo, como o status ou o valor mais recente de um tópico específico. Quando um novo cliente se inscreve em um tópico, ele recebe a última mensagem retida, garantindo que tenha as informações mais atualizadas.
Manter-Vivo
Para garantir alta disponibilidade em caso de erros ou quedas de conexão, defina intervalos de keep-alive adequados para a comunicação cliente-servidor. Durante os períodos ociosos, os clientes enviam PINGREQs, aguardando PINGRESPs. Se não houver resposta, implemente a lógica de reconexão automática no cliente para restabelecer as conexões. A maioria dos clientes como a Paho tem lógica de repetição incorporada. Como o broker MQTT é tolerante a falhas, uma reconexão será bem-sucedida se houver pelo menos duas instâncias de broker íntegros, um frontend e um backend.
Eventual consistência com a assinatura QoS-1
As assinaturas MQTT com QoS-1 garantem uma eventual consistência em instâncias de aplicativos idênticas assinando um tópico compartilhado. À medida que as mensagens são publicadas, as instâncias recebem e replicam dados com entrega pelo menos uma vez. As instâncias devem lidar com duplicatas e tolerar inconsistências temporárias até que os dados sejam sincronizados.
Subscrições partilhadas
As assinaturas compartilhadas permitem o balanceamento de carga em várias instâncias de um aplicativo altamente disponível. Em vez de cada assinante receber uma cópia de cada mensagem, as mensagens são distribuídas uniformemente entre os assinantes. Atualmente, o broker MQTT suporta apenas um algoritmo round robin para distribuir mensagens, permitindo que um aplicativo seja dimensionado. Um caso de uso típico é implantar vários pods usando o Kubernetes ReplicaSet que todos assinam o broker MQTT usando o mesmo filtro de tópico na assinatura compartilhada.
Armazenamento de estado
O armazenamento de estado é um HashMap replicado na memória para gerenciar o estado de processamento do aplicativo. Ao contrário do etcd, por exemplo, o armazenamento de estado prioriza a taxa de transferência de alta velocidade, o dimensionamento horizontal e a baixa latência por meio de estruturas de dados na memória, particionamento e replicação em cadeia. Ele permite que os aplicativos usem os armazenamentos de estado, natureza distribuída e tolerância a falhas enquanto acessam um estado consistente rapidamente entre instâncias. Para usar o armazenamento de chave-valor interno fornecido pelo broker distribuído:
Implemente operações efêmeras de armazenamento e recuperação usando a API de armazenamento de chave-valor do broker, garantindo o tratamento adequado de erros e a consistência dos dados. O estado efêmero é um armazenamento de dados de curta duração usado no processamento stateful para acesso rápido a resultados intermediários ou metadados durante cálculos em tempo real. No contexto do aplicativo HA, um estado efêmero ajuda a recuperar estados do aplicativo entre falhas. Ele pode ser gravado em disco, mas permanece temporário, ao contrário do armazenamento a frio projetado para armazenamento de longo prazo de dados acessados com pouca frequência.
Use o armazenamento de estado para compartilhar estado, cache, configuração ou outros dados essenciais entre várias instâncias do aplicativo, permitindo que eles mantenham uma exibição consistente dos dados.
Use a integração Dapr integrada do broker MQTT
Para casos de uso mais simples, um aplicativo pode utilizar Dapr (Distributed Application Runtime). O Dapr é um tempo de execução de código aberto, portátil e orientado a eventos que simplifica a criação de microsserviços e aplicativos distribuídos. Ele oferece um conjunto de blocos de construção, como chamada de serviço a serviço, gerenciamento de estado e mensagens de publicação/assinatura.
O Dapr é oferecido como parte do corretor MQTT, abstraindo detalhes do gerenciamento de sessões MQTT, QoS e reconhecimento de mensagens e armazenamentos de chave-valor integrados, tornando-o uma escolha prática para desenvolver um aplicativo altamente disponível para casos de uso simples por:
Projete seu aplicativo usando os blocos de construção do Dapr, como gerenciamento de estado para lidar com o armazenamento de chave-valor e mensagens de publicação/assinatura para interagir com o broker MQTT. Se o caso de uso exigir blocos de construção e abstrações que não são suportados pelo Dapr, considere usar os recursos do broker MQTT mencionados anteriormente.
Implemente o aplicativo usando sua linguagem de programação e estrutura preferidas, aproveitando SDKs ou APIs do Dapr para uma integração perfeita com o broker e o armazenamento de chave-valor.
Lista de verificação para desenvolver uma aplicação altamente disponível
- Escolha uma biblioteca de cliente MQTT apropriada para sua linguagem de programação. O cliente deve suportar MQTT v5. Use uma biblioteca baseada em C ou Rust se seu aplicativo for sensível à latência.
- Configure a biblioteca do cliente para se conectar ao broker MQTT com o sinalizador de sessão limpa definido como
false
e o nível de QoS desejado (QoS-1). - Decida um valor adequado para expiração da sessão, expiração da mensagem e intervalos de keep-alive.
- Implemente a lógica de processamento de mensagens para o aplicativo do assinante, incluindo o envio de uma confirmação quando a mensagem tiver sido entregue ou processada com êxito.
- Para aplicativos multithreaded, configure o parâmetro max-receive para habilitar o processamento paralelo de mensagens.
- Utilize mensagens retidas para manter o estado temporário do aplicativo.
- Utilize o armazenamento de estado distribuído para gerenciar o estado efêmero do aplicativo.
- Avalie o Dapr para desenvolver seu aplicativo se o seu caso de uso for simples e não exigir controle detalhado sobre a conexão MQTT ou o tratamento de mensagens.
- Implemente assinaturas compartilhadas para distribuir mensagens uniformemente entre várias instâncias do aplicativo, permitindo um dimensionamento eficiente.