Partilhar via


Aplicativos de borda altamente disponíveis para Operações do Azure IoT

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 são perdidas e podem 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 embutido, fornecido pelo intermediário 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 que é 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.

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 de assinante, incluindo o envio de uma confirmação quando a mensagem for 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.
  • Implemente assinaturas compartilhadas para distribuir mensagens uniformemente entre várias instâncias do aplicativo, permitindo um dimensionamento eficiente.