Pyxis Logo
Início / Formação IBM / Artigo técnico

Alta Disponibilidade Nativa (Native HA) em Docker: Resiliência Cloud-Native

Como configurar o IBM MQ Native HA utilizando Docker, volumes de configuração e demonstrar o ACR (Automatic Client Reconnect) com um nó de cliente dedicado.

20 min de leitura
Publicado 2026-05-14
Pyxis editorial team
Classifique este artigo
Classificação média: Sem classificação
A sua classificação: Sem classificação
visualizações: 0
Diagrama de três contentores MQ em replicação síncrona

Historicamente, a Alta Disponibilidade (HA) no IBM MQ dependia de storage partilhado ou de replicação externa (RDQM). Em arquiteturas modernas de micro-serviços e cloud (Kubernetes, OpenShift, Docker), o storage partilhado introduz complexidade e latência.

O Native HA utiliza um algoritmo de consenso (Raft) para replicar dados entre três instâncias independentes. Este lab demonstra como subir um cluster resiliente de 3 nós usando Docker Compose, utilizando ficheiros de configuração (qm.ini) montados via volumes para garantir 100% de fiabilidade na versão 9.4+. Além disso, demonstraremos o Automatic Client Reconnect (ACR) utilizando um quarto nó como cliente.

Como funciona o MQ Native HA?

O MQ Native HA foi desenhado para eliminar a dependência de tecnologias de storage partilhado (como NFS ou SAN), que são frequentemente complexas e lentas em ambientes de nuvem.

1. O Protocolo Raft e o Quorum

O Native HA baseia-se no algoritmo de consenso Raft. Num grupo de três instâncias, os nós comunicam continuamente para eleger um Líder (Active). As outras duas instâncias tornam-se Réplicas.

  • Quorum: Para que o cluster aceite mensagens, a maioria dos nós (2 em 3) deve estar funcional e em comunicação. Isto evita o "Split-brain", onde dois nós poderiam tentar ser ativos simultaneamente, corrompendo os dados.
  • Eleição Automática: Se o Líder falhar, as Réplicas detectam a ausência de "heartbeats" e iniciam uma nova eleição. O nó com o log de recuperação mais atualizado é eleito o novo Líder.

2. Replicação Síncrona

Ao contrário de outras soluções, o MQ Native HA replica os dados ao nível do log de recuperação. Quando uma aplicação envia uma mensagem persistente: 1. O Líder escreve a mensagem no seu log local. 2. O Líder envia os dados do log para as Réplicas. 3. Assim que pelo menos uma Réplica confirma a receção (garantindo a maioria), o Líder confirma o sucesso à aplicação.

3. Limitações e Comportamento das Réplicas

É fundamental compreender que as Réplicas não são "nós ativos de leitura". Existem limitações operacionais estritas:

  • Estado de Standby: As Réplicas estão num estado de "espera quente". Não processam mensagens nem permitem que aplicações se liguem a elas (via canais ou localmente).
  • Sem Conectividade de Aplicação: Se tentar ligar uma aplicação a uma Réplica, receberá um erro de "Queue Manager Not Available" (MQRC_Q_MGR_NOT_AVAILABLE).
  • Administração Limitada: Comandos como runmqsc têm funcionalidades muito restritas nas Réplicas, servindo apenas para consultar o estado do HA.

4. Automatic Client Reconnect (ACR)

O Automatic Client Reconnect (ACR) é uma funcionalidade das bibliotecas do cliente IBM MQ que permite a resiliência transparente do lado da aplicação.

Como funciona:

  • Transparência: Se a ligação for interrompida, o cliente MQ suspende a operação da aplicação em vez de devolver um erro imediato.
  • Retry Automático: O cliente MQ consulta a lista de nomes de conexão (CONNAME) configurada e tenta restabelecer a sessão com os outros nós.
  • Failover em Native HA: Num cluster Native HA, o cliente tentará ligar-se às Réplicas (que rejeitarão a ligação) até encontrar o novo Líder (Active). Uma vez ligado, o processamento retoma automaticamente, preservando a integridade das mensagens.

O que acontece tecnicamente no cliente MQI:

  • Ligação elegível para reconnect: O cliente tem de usar transporte client e uma lista de endereços alternativa, normalmente via CONNAME, CCDT, MQSERVER ou mqclient.ini.
  • Reconnect inline: Quando a falha é detetada, o cliente tenta restabelecer a ligação sem obrigar a aplicação a executar um novo MQCONN ou MQCONNX.
  • Restauro de contexto: Se a reconexão for bem-sucedida, os handles de ligação e de objetos são recriados pelo cliente. Para muitas aplicações MQI, isto significa retoma do processamento com impacto mínimo.
  • Espera mais longa durante a chamada MQI: Se a falha ocorrer a meio de uma chamada, a aplicação pode observar apenas uma espera prolongada até a operação terminar ou falhar definitivamente.
  • Nem todas as APIs se comportam da mesma forma: Neste lab vamos usar amqsphac, um sample IBM MQ desenhado especificamente para demonstrar reconexão automática em cenários de alta disponibilidade. O sample usa MQCNO_RECONNECT no MQCONNX e mantém o loop de aplicação ativo durante a reconexão — o que samples genéricos como amqsputc não fazem. ACR no sentido MQI não é suportado pelas IBM MQ classes for Java; para JMS existe um mecanismo próprio de reconexão automática.

Anatomia da Configuração (qm.ini)

A configuração lógica do Native HA reside nas stanzas NativeHALocalInstance e NativeHAInstance, que fazem parte da configuração do queue manager. Em instalações Linux convencionais, isto significa editar o qm.ini de cada instância.

Neste lab com contentores, vamos manter essas stanzas em ficheiros dedicados node1.ini, node2.ini e node3.ini, montados como /etc/mqm/nativeha.ini. O importante é o conteúdo das stanzas, não o nome do ficheiro no host. O container image consome esse ficheiro montado para inicializar a configuração do Native HA.

A configuração divide-se em duas secções principais:

NativeHALocalInstance

Define a identidade do nó atual.

  • Name: O nome único desta instância (ex: node1).

NativeHAInstance

Define todos os membros que participam no grupo HA. Deve haver uma entrada para cada um dos 3 nós.

  • Name: Nome único da instância.
  • ReplicationAddress: O endereço IP ou Hostname e a porta dedicada exclusivamente ao tráfego de replicação do Raft.

O que este lab constrói

No fim deste lab, terá:

  • Um cluster de 3 contentores MQ comunicando via rede Docker.
  • Configuração baseada em ficheiros com stanzas equivalentes ao qm.ini, simulando implementações empresariais.
  • Um nó de Cliente dedicado que demonstra a reconexão automática (ACR).
  • Replicação síncrona de logs sem necessidade de storage partilhado.

Preparação do Ambiente: Instalação do Software

Antes de iniciar o lab, deve garantir que tem as ferramentas de containerização necessárias e acesso à imagem oficial do MQ.

Também precisa de uma destas duas condições no host Linux:

  • acesso a sudo
  • ou pertença ao grupo docker, para executar Docker sem sudo

Se não tiver nenhuma destas opções, não conseguirá executar este lab tal como está descrito.

1. Instalar Docker e Docker Compose

O Docker é a plataforma base para este lab. O Docker Compose permite orquestrar os 3 nós MQ de forma simples.

  • Windows/macOS: Instale o Docker Desktop. O Docker Compose já vem incluído.
  • Linux (Ubuntu/Debian):
  # Ensure curl is installed
  sudo apt-get update && sudo apt-get install -y curl
  # Install Docker
  curl -fsSL https://get.docker.com -o get-docker.sh
  sudo sh get-docker.sh
  # Install Docker Compose
  sudo apt-get install -y docker-compose-plugin
  • Linux (RHEL/CentOS/Fedora):
  # Remove old versions
  sudo dnf remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
  # Setup the repository
  sudo dnf -y install dnf-plugins-core
  sudo dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo
  # Install Docker and Compose
  sudo dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
  # Start the service
  sudo systemctl enable --now docker

Confirme a instalação:

docker version
docker compose version

Configuração de Permissões (Linux)

Se receber um erro de "permission denied" ao executar comandos do Docker, o seu utilizador precisa de ser adicionado ao grupo docker:

sudo usermod -aG docker $USER

Nota: Deve executar sudo newgrp docker ou fazer logout/login para aplicar as alterações.

Se preferir não alterar já os grupos do sistema, pode simplesmente executar os comandos deste lab com sudo, tal como já aparecem nos blocos executados no host.

Confirme antes de prosseguir:

docker version

Se este comando falhar e também não tiver como obter acesso ao grupo docker, pare aqui e resolva primeiro o acesso ao daemon Docker.

2. Obter a Imagem do IBM MQ

Basta executar o comando:

docker pull icr.io/ibm-messaging/mq:latest

1. Criar os Ficheiros de Configuração

MQ Nodes (.ini)

Vamos criar três ficheiros de configuração distintos para cada nó.

Crie o ficheiro para o node1:

cat > node1.ini <<'EOF'
NativeHALocalInstance:
    Name=node1
NativeHAInstance:
    Name=node1
    ReplicationAddress=node1(5000)
NativeHAInstance:
    Name=node2
    ReplicationAddress=node2(5000)
NativeHAInstance:
    Name=node3
    ReplicationAddress=node3(5000)
EOF

Crie o ficheiro para o node2:

cat > node2.ini <<'EOF'
NativeHALocalInstance:
    Name=node2
NativeHAInstance:
    Name=node1
    ReplicationAddress=node1(5000)
NativeHAInstance:
    Name=node2
    ReplicationAddress=node2(5000)
NativeHAInstance:
    Name=node3
    ReplicationAddress=node3(5000)
EOF

Crie o ficheiro para o node3:

cat > node3.ini <<'EOF'
NativeHALocalInstance:
    Name=node3
NativeHAInstance:
    Name=node1
    ReplicationAddress=node1(5000)
NativeHAInstance:
    Name=node2
    ReplicationAddress=node2(5000)
NativeHAInstance:
    Name=node3
    ReplicationAddress=node3(5000)
EOF

Ficheiro de Configuração MQ (config.mqsc)

Crie o ficheiro com toda a configuração de segurança e fila. O IBM MQ Docker image executa automaticamente ficheiros .mqsc montados em /etc/mqm/ no arranque do nó ativo — os réplicas recebem a mesma configuração por replicação Raft:

cat > config.mqsc <<'EOF'
DEFINE CHANNEL(DEV.APP.SVRCONN) CHLTYPE(SVRCONN) REPLACE
ALTER CHANNEL(DEV.APP.SVRCONN) CHLTYPE(SVRCONN) MCAUSER('mqm')
SET CHLAUTH(DEV.APP.SVRCONN) TYPE(BLOCKUSER) USERLIST('nobody') ACTION(REPLACE)
ALTER QMGR CHLAUTH(DISABLED)
ALTER QMGR CONNAUTH('')
REFRESH SECURITY(*) TYPE(CONNAUTH)
DEFINE QLOCAL(HA.TEST.QUEUE) DEFPSIST(YES) REPLACE
EOF

2. O Ficheiro de Orquestração (Cluster + Cliente)

Recrie o ficheiro:

rm -f docker-compose.yaml

Depois, abra o ficheiro:

vi docker-compose.yaml

E cole exatamente este conteúdo:

services:
  mq-node1:
    container_name: mq-node1
    hostname: node1
    image: icr.io/ibm-messaging/mq:latest
    environment:
      LICENSE: "accept"
      MQ_QMGR_NAME: "QM_HA"
      MQ_NATIVE_HA: "true"
      MQ_NATIVE_HA_INSTANCE_NAME: "node1"
    volumes:
      - ./node1.ini:/etc/mqm/nativeha.ini
      - ./config.mqsc:/etc/mqm/20-config.mqsc
    ports:
      - "1414:1414"

  mq-node2:
    container_name: mq-node2
    hostname: node2
    image: icr.io/ibm-messaging/mq:latest
    environment:
      LICENSE: "accept"
      MQ_QMGR_NAME: "QM_HA"
      MQ_NATIVE_HA: "true"
      MQ_NATIVE_HA_INSTANCE_NAME: "node2"
    volumes:
      - ./node2.ini:/etc/mqm/nativeha.ini
      - ./config.mqsc:/etc/mqm/20-config.mqsc
    ports:
      - "1415:1414"

  mq-node3:
    container_name: mq-node3
    hostname: node3
    image: icr.io/ibm-messaging/mq:latest
    environment:
      LICENSE: "accept"
      MQ_QMGR_NAME: "QM_HA"
      MQ_NATIVE_HA: "true"
      MQ_NATIVE_HA_INSTANCE_NAME: "node3"
    volumes:
      - ./node3.ini:/etc/mqm/nativeha.ini
      - ./config.mqsc:/etc/mqm/20-config.mqsc
    ports:
      - "1416:1414"

  mq-client:
    container_name: mq-client
    image: icr.io/ibm-messaging/mq:latest
    environment:
      LICENSE: "accept"
    command: sleep infinity

3. Iniciar o Cluster

Inicie os contentores:

docker compose down -v
docker compose up -d

Aguarde alguns segundos e confirme que o cluster está estável e que o ficheiro config.mqsc foi aplicado:

for c in mq-node1 mq-node2 mq-node3; do echo "== $c ==" && docker exec "$c" dspmq -o nativeha -m QM_HA 2>/dev/null || true; done

O esperado é observar um nó com ROLE(Active) e os outros dois com ROLE(Replica). Se os contentores ainda estiverem a inicializar, aguarde mais alguns segundos e repita.

Identifique o nó ativo e confirme que a fila e o canal foram criados automaticamente pelo config.mqsc:

ACTIVE_NODE=$(for c in mq-node1 mq-node2 mq-node3; do docker exec "$c" dspmq -o nativeha -m QM_HA 2>/dev/null | grep -q "ROLE(Active)" && echo "$c" && break; done) && echo "Active node: $ACTIVE_NODE"
docker exec "$ACTIVE_NODE" bash -lc 'echo "DISPLAY QLOCAL(HA.TEST.QUEUE) CURDEPTH" | runmqsc QM_HA'
docker exec "$ACTIVE_NODE" bash -lc 'echo "DISPLAY CHANNEL(DEV.APP.SVRCONN) MCAUSER" | runmqsc QM_HA'

4. Teste de Quorum e Replicação Síncrona

Nesta primeira fase, vamos provar que o cluster sobrevive e mantém os dados consistentes internamente.

Passo 1: Colocar Mensagem no Líder

Identifique qual o nó ativo e guarde-o numa variável:

ACTIVE_NODE=$(
  for c in mq-node1 mq-node2 mq-node3; do
    if docker exec "$c" dspmq -o nativeha -m QM_HA 2>/dev/null | grep -q "ROLE(Active)"; then
      echo "$c"
      break
    fi
  done
)

echo "Active node: $ACTIVE_NODE"

Depois, coloque uma mensagem nesse nó:

docker exec -it "$ACTIVE_NODE" /opt/mqm/samp/bin/amqsput HA.TEST.QUEUE QM_HA

Escreva: "Validando replicação síncrona" e pressione Enter duas vezes.

Passo 2: Simular Falha (Stop Container)

Pare o contentor que está ativo:

docker stop "$ACTIVE_NODE"

Passo 3: Verificar Eleição e Consistência

Verifique quem é o novo líder e guarde-o numa variável:

NEW_ACTIVE_NODE=$(
  for c in mq-node1 mq-node2 mq-node3; do
    if docker exec "$c" dspmq -o nativeha -m QM_HA 2>/dev/null | grep -q "ROLE(Active)"; then
      echo "$c"
      break
    fi
  done
)

echo "New active node: $NEW_ACTIVE_NODE"

Recupere aí a mensagem:

docker exec -it "$NEW_ACTIVE_NODE" /opt/mqm/samp/bin/amqsget HA.TEST.QUEUE QM_HA

O sucesso prova que a mensagem foi replicada para o log local do novo líder antes da queda do nó originalmente ativo.

5. Demonstração de ACR (Automatic Client Reconnect)

Agora que validámos o backend, vamos testar a resiliência do lado da aplicação com o sample amqsphac, que usa MQCNO_RECONNECT internamente e mantém o loop de envio ativo durante e após o failover.

Passo 1: Garantir que o cluster está operacional

docker start mq-node1 && docker start mq-node2 && docker start mq-node3
ACTIVE_NODE=$(for c in mq-node1 mq-node2 mq-node3; do docker exec "$c" dspmq -o nativeha -m QM_HA 2>/dev/null | grep -q "ROLE(Active)" && echo "$c" && break; done) && echo "Active node: $ACTIVE_NODE"

Passo 2: Criar o script de arranque do sample

Escreva o script linha a linha para evitar problemas com a colagem de comandos multi-linha:

docker exec mq-client bash -c 'echo "#!/bin/bash" > /tmp/acr.sh'
docker exec mq-client bash -c 'echo "export MQSERVER=\"DEV.APP.SVRCONN/TCP/node1(1414),node2(1414),node3(1414)\"" >> /tmp/acr.sh'
docker exec mq-client bash -c 'echo "/opt/mqm/samp/bin/amqsphac HA.TEST.QUEUE QM_HA" >> /tmp/acr.sh'
docker exec mq-client bash -c 'chmod +x /tmp/acr.sh'

Passo 3: Iniciar o sample em background

docker exec -d mq-client bash -c '/tmp/acr.sh'

O amqsphac não produz output linha a linha em modo não-interativo (buffering de stdout), por isso a verificação é feita pela profundidade da fila. Confirme que as mensagens estão a chegar ao nó ativo:

sleep 5 && docker exec "$ACTIVE_NODE" bash -lc 'echo "DISPLAY QLOCAL(HA.TEST.QUEUE) CURDEPTH" | runmqsc QM_HA'

O CURDEPTH deve estar a crescer continuamente.

Passo 4: Provocar a falha do nó ativo

docker stop "$ACTIVE_NODE"

Passo 5: Verificar a eleição do novo líder

NEW_ACTIVE_NODE=$(for c in mq-node1 mq-node2 mq-node3; do docker exec "$c" dspmq -o nativeha -m QM_HA 2>/dev/null | grep -q "ROLE(Active)" && echo "$c" && break; done) && echo "New active node: $NEW_ACTIVE_NODE"

Passo 6: Confirmar a reconexão automática pelo crescimento da fila

Aguarde cerca de 10 segundos para a eleição completar e verifique o CURDEPTH no novo líder:

sleep 10 && docker exec "$NEW_ACTIVE_NODE" bash -lc 'echo "DISPLAY QLOCAL(HA.TEST.QUEUE) CURDEPTH" | runmqsc QM_HA'

Se o CURDEPTH estiver a crescer no novo líder, o amqsphac reconectou automaticamente sem qualquer intervenção — o ACR funcionou.

Passo 7: Confirmar as mensagens recebidas

docker exec -it "$NEW_ACTIVE_NODE" /opt/mqm/samp/bin/amqsget HA.TEST.QUEUE QM_HA

Principais Conclusões para Docker

  • Resiliência em Camadas: Validámos primeiro a replicação de dados e depois a continuidade da aplicação.
  • ACR & Native HA: A combinação perfeita para arquiteturas de alta disponibilidade total. O amqsphac usa MQCNO_RECONNECT para demonstrar a reconexão transparente que uma aplicação real deve implementar.
  • Configuração Robusta: O uso de volumes para montar as stanzas de configuração do Native HA é a abordagem mais fiável.

Cleanup

No fim do lab, pode remover os contentores e os ficheiros criados durante a experiência:

docker compose down -v
rm -f node1.ini node2.ini node3.ini config.mqsc docker-compose.yaml

Este cleanup não desinstala Docker, Docker Compose ou a imagem do IBM MQ. Remove apenas os artefactos locais usados neste lab.

Documentação Útil

Mais nesta área

Mais nesta área

Voltar à formação
Categoria de artigos

Artigos de IBM MQ

Veja todos os artigos técnicos de IBM MQ numa única página de categoria.

Abrir categoria IBM MQ