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

Replicação entre regiões do IBM MQ na prática

Crie dois grupos Native HA do IBM MQ com três nós num único host Docker, proteja a replicação entre regiões com TLS, valide a recuperação assíncrona e execute um failover planeado.

25 min de leitura
Publicado 2026-07-13
Pyxis editorial team
Classifique este artigo
Classificação média: Sem classificação
A sua classificação: Sem classificação
visualizações: 0
Dois grupos Native HA de três instâncias ligados por replicação direcional entre regiões

O Native HA do IBM MQ recorre a replicarão síncrona e protege um Queue Manager contra falhas dentro de um mesmo site. A replicação entre regiões (CRR) adiciona um segundo grupo de Native HA e copia de forma assíncrona os dados do log de recuperação para este, fornecendo um destino de recuperação de desastres em outro local o qual poderá ser distante.

Este artigo cria a topologia completa em um host Docker recorrendo a uma máquina virtual Intel/AMD64 Linux ou Docker Desktop no macOS. O laboratório usa seis containers IBM MQ: três instâncias em um grupo denominado london e três instâncias em um grupo denominado rome. Londres começa na função Live, enquanto Roma começa na função Recovery.

A configuração numa única VM é deliberadamente compacta e permite estudar funções de grupo, quórum, replicação protegida por TLS, backlog de recuperação e uma alternância planeada sem primeiro aprovisionar dois centros de dados.

Limitações do laboratório: esta topologia demonstra o comportamento do MQ, e não a resiliência real da infraestrutura. Todos os seis container compartilham um host Docker, um subsistema de armazenamento e um domínio de falha. A IBM apresenta Kubernetes ou Red Hat OpenShift como a infraestrutura suportada para containers com Native HA CRR e recomenda o uso do operador de IBM MQ. Use este laboratório do Docker Compose apenas para aprendizagem dos conceitos básicos.

1. O que este laboratório constrói

A topologia final é:

IBM MQ CRR topologia com Londres como o grupo Live de três instâncias e Roma como o grupo de recuperação de três instâncias

Cada grupo contém três instâncias do mesmo Queue Manager, CRRQM.

  • Dentro de cada grupo, Native HA usa replicação de log síncrona e quórum.
  • Entre os grupos, o CRR usa replicação de log assíncrona.
  • Somente o grupo Live aceita workload aplicacional.
  • O líder de recuperação recebe dados de log, mas não aceita conexões normais do aplicação MQ.
  • Uma transição planeada coordena ambos os grupos e espera que seus logs sincronizem.

Este laboratório valida os seguintes items:

  1. Ambos os grupos nativos HA atingem o quórum.
  2. London elege um gestor de filas ativo.
  3. Rome elege um líder de recuperação.
  4. Os grupos conectam-se entre si usando TLS.
  5. Uma mensagem persistente é transmitida ao grupo de recuperação.
  6. Uma mudança planeada torna Roma no grupo Live sem perder a mensagem.

2. Requisitos e limitações importantes

Use um destes ambientes:

  • Uma VM Intel/AMD64 (uname -m deverá mostrar x86_64) ou
  • Um Mac executando Docker Desktop, incluindo Apple Silicon com suporte Rosetta do Docker Desktop habilitado

Alocar:

  • Pelo menos 12 GB RAM; 16 GB é mais confortável
  • Pelo menos 30 GB de espaço livre em disco
  • Acesso à Internet para icr.io
  • Docker Engine e Docker Compose v2 já instalados. As instruções de instalação podem ser encontradas no Apêndice A

Requisito de arquitetura: a imagem IBM MQ Advanced for Developers pré-construída usada aqui é linux/amd64. Não use um ARM64 Linux VM para este laboratório. No Apple Silicon, o Docker Desktop gere a execução do AMD64 dentro da seu própria VM Linux.

O CRR precisa de mais armazenamento do que uma implementação Native HA normal.

Este artigo usa a imagem IBM MQ Advanced for Developers. Sua licença restringe o uso de desenvolvimento em uma máquina de desenvolvedor. A produção CRR requer o direito IBM MQ Advanced apropriado ou o complemento IBM MQ Native HA e replicação entre regiões.

O laboratório fixa a imagem do desenvolvedor IBM MQ 10.0 em vez de usar latest. Fixar 10.0.0.0-r2 torna o exercício repetível e garante que os recursos nativos do Linux HA CRR usados ​​abaixo estejam presentes.

3. Crie a pasta do laboratório e extraia IBM MQ

Crie uma pasta de trabalho vazia:

mkdir -p "$HOME/mq-crr-lab/config" "$HOME/mq-crr-lab/tls"
cd "$HOME/mq-crr-lab"

Mantenha a imagem de desenvolvedor MQ 10.0 atual para o Compose e exporte-a para comandos no shell atual:

cat > .env <<'EOF'
MQ_IMAGE=icr.io/ibm-messaging/mq:10.0.0.0-r2
EOF

set -a
. ./.env
set +a

printf 'MQ image: <%s>\n' "$MQ_IMAGE"

Os colchetes na saída devem conter a referência completa da imagem. Docker Compose lê .env automaticamente. Após abrir um novo terminal, retorne à pasta lab e recarregue a variável antes de usar os comandos docker pull ou docker run independentes:

cd "$HOME/mq-crr-lab"
set -a
. ./.env
set +a

Verifique se o Container Registry IBM é resolvido e está acessível:

case "$(uname -s)" in
  Linux) getent ahosts icr.io ;;
  Darwin) dscacheutil -q host -a name icr.io ;;
esac
curl -I https://icr.io/v2/

Uma resposta HTTP 401 Unauthorized de /v2/ é esperada. Isso prova que DNS, TCP, TLS e o endpoint do registo estão funcionando. A autenticação não é necessária para obter a imagem pública.

Obtenha a imagem:

docker pull --platform linux/amd64 "$MQ_IMAGE"

Se o Docker no Linux relatar um erro lookup icr.io ... no such host transitório, mesmo que as duas verificações acima funcionem, reinicie o daemon e tente novamente:

sudo systemctl restart docker
docker pull --platform linux/amd64 "$MQ_IMAGE"

No macOS, use Docker Desktop > Solucionar problemas > Reiniciar Docker Desktop e repita o comando pull.

Confirme a versão MQ na imagem:

docker run --rm --platform linux/amd64 --entrypoint dspmqver "$MQ_IMAGE"

O resultado deve mostrar IBM MQ versão 10.0.0.0.

Antes de iniciar seis instâncias, prove que um Queue Manager pode ser iniciado corretamente neste host. Esses comandos assumem que docker version funciona sem sudo.

docker rm -f mq-platform-test >/dev/null 2>&1 || true

docker run -d --name mq-platform-test \
  --platform linux/amd64 \
  -e LICENSE=accept \
  -e MQ_QMGR_NAME=PLATFORMQM \
  "$MQ_IMAGE"

MQ_READY=0
for attempt in $(seq 1 60); do
  if docker exec mq-platform-test \
      dspmq -m PLATFORMQM 2>/dev/null | grep -Fq 'STATUS(Running)'; then
    MQ_READY=1
    break
  fi
  printf '.'
  sleep 3
done
printf '\n'

if [ "$MQ_READY" -eq 1 ]; then
  echo "PLATFORMQM is running."
  docker exec mq-platform-test dspmq -m PLATFORMQM
  docker logs --tail 20 mq-platform-test
  docker rm -f mq-platform-test
else
  echo "The test queue manager did not become ready within three minutes."
  docker logs --tail 100 mq-platform-test
  echo "The container was left running for diagnosis."
fi

O estado do Queue Manager é verificado com o comando dspmq.

4. Por que motivo usamos TLS no laboratório

O IBM MQ requer TLS para replicação de log entre grupos Native HA. O TLS dentro de cada grupo de três instâncias é opcional, mas recomendado. Para manter o exercício gerível, todas as seis instâncias usam o mesmo certificado auto-assinado e repositório de chaves.

Esta simplificação é adequada apenas para cenários de laboratórios.

Crie a base de dados para chaves usando as ferramentas MQ já presentes na imagem do container:

docker run --rm --platform linux/amd64 --user 0 \
  -v "$PWD/tls:/work" \
  --entrypoint /bin/bash \
  "$MQ_IMAGE" -lc '
    set -e
    runmqakm -keydb -create \
      -db /work/keystore.kdb \
      -pw passw0rd \
      -stash
    runmqakm -cert -create \
      -db /work/keystore.kdb \
      -pw passw0rd \
      -label nha-qm-replication \
      -dn "CN=CRRQM-REPLICATION" \
      -size 2048
    chmod 644 /work/keystore.*
  '

Confira os ficheiros:

ls -l tls/keystore.*

O caminho do repositório de chaves usado por MQ omite o sufixo .kdb, portanto a configuração se referirá a /etc/mqm/tls/keystore.

5. Crie as duas configurações nativas HA

Cada instância precisa de seu próprio nome NativeHALocalInstance. Caso contrário, todas as instâncias em um grupo usarão a mesma lista de membros e endereços de grupo de recuperação.

Crie um pequeno script auxiliar que grave os seis ficheiros de configuração:

cat > make-config.sh <<'SCRIPT'
#!/usr/bin/env bash
set -euo pipefail

mkdir -p config

write_london() {
  local instance=$1
  cat > "config/${instance}.ini" <<EOF
NativeHALocalInstance:
    Name=${instance}
    GroupName=london
    GroupRole=Live
    GroupLocalAddress=(9415)
    CipherSpec=ANY_TLS12
    GroupCipherSpec=ANY_TLS12
    CertificateLabel=nha-qm-replication
    KeyRepository=/etc/mqm/tls/keystore
NativeHAInstance:
    Name=london1
    ReplicationAddress=london1(9414)
NativeHAInstance:
    Name=london2
    ReplicationAddress=london2(9414)
NativeHAInstance:
    Name=london3
    ReplicationAddress=london3(9414)
NativeHARecoveryGroup:
    GroupName=rome
    ReplicationAddress=rome1(9415),rome2(9415),rome3(9415)
    Enabled=Yes
EOF
}

write_rome() {
  local instance=$1
  cat > "config/${instance}.ini" <<EOF
NativeHALocalInstance:
    Name=${instance}
    GroupName=rome
    GroupRole=Recovery
    GroupLocalAddress=(9415)
    CipherSpec=ANY_TLS12
    GroupCipherSpec=ANY_TLS12
    CertificateLabel=nha-qm-replication
    KeyRepository=/etc/mqm/tls/keystore
NativeHAInstance:
    Name=rome1
    ReplicationAddress=rome1(9414)
NativeHAInstance:
    Name=rome2
    ReplicationAddress=rome2(9414)
NativeHAInstance:
    Name=rome3
    ReplicationAddress=rome3(9414)
NativeHARecoveryGroup:
    GroupName=london
    ReplicationAddress=london1(9415),london2(9415),london3(9415)
    Enabled=Yes
EOF
}

for instance in london1 london2 london3; do
  write_london "$instance"
done

for instance in rome1 rome2 rome3; do
  write_rome "$instance"
done
SCRIPT

chmod +x make-config.sh
./make-config.sh

Revise um ficheiro de cada grupo:

cat config/london1.ini
cat config/rome1.ini

Os atributos CRR importantes são:

AtributoFinalidade
GroupNameIdentifica o grupo local de três instâncias.
GroupRoleSolicita o comportamento Live ou Recovery.
GroupLocalAddressAbre o endpoint de replicação local de grupo para grupo.
GroupCipherSpecRequer TLS para conexão entre grupos.
NativeHARecoveryGroupNomeia o outro grupo e lista os endereços através dos quais MQ pode localizá-lo.

Nomes como london e rome descrevem locais em vez de funções. Isto é importante porque os papéis serão invertidos durante a transição.

6. Crie a configuração do objeto MQ

Crie uma fila persistente e um canal de cliente. As definições de objeto são aplicadas quando o Queue Manager Live é iniciado pela primeira vez e, em seguida, são replicadas com os dados do Queue Manager.

cat > config/20-config.mqsc <<'EOF'
DEFINE QLOCAL('CRR.TEST.QUEUE') DEFPSIST(YES) REPLACE
DEFINE CHANNEL('DEV.APP.SVRCONN') CHLTYPE(SVRCONN) REPLACE
ALTER CHANNEL('DEV.APP.SVRCONN') CHLTYPE(SVRCONN) MCAUSER('mqm')
ALTER QMGR CHLAUTH(DISABLED)
ALTER QMGR CONNAUTH('')
REFRESH SECURITY(*) TYPE(CONNAUTH)
EOF

As modificações acima destinam-se a desativar mecanismos de segurança de forma a simplificar a demonstração no laboratório. Nunca as use como modelo de segurança de produção.

7. Crie a topologia Docker Compose

O ficheiro Docker Compose é compartilhado pelo Intel/AMD64 Linux e Docker Desktop no macOS. platform: linux/amd64 é nativo no VM Linux e seleciona o caminho de execução AMD64 do Docker Desktop no Apple Silicon. Os dados do Queue Manager usam volumes nomeados Docker para evitar diferenças de propriedade no caminho do host. Os shared read-only bind mounts usam a opção SELinux z, que o Compose ignora em plataformas onde o SELinux não esteja ativo.

Os serviços não publicam portas MQ no host. Cada comando usado para as validações é executado através de docker exec, e Native HA e CRR comunicam pela rede privada Docker. Isso evita colisões com outro container MQ local que já use uma das portas (exemplo: 1414).

Abra um editor de texto e cole o seguinte conteúdo para criar o ficheiro docker-compose.yaml:

services:
  london1:
    container_name: crr-london1
    hostname: london1
    image: ${MQ_IMAGE:-icr.io/ibm-messaging/mq:10.0.0.0-r2}
    platform: linux/amd64
    environment:
      LICENSE: "accept"
      MQ_QMGR_NAME: "CRRQM"
      MQ_NATIVE_HA: "true"
      MQ_NATIVE_HA_INSTANCE_NAME: "london1"
    volumes:
      - london1-data:/mnt/mqm
      - ./config/london1.ini:/etc/mqm/nativeha.ini:ro,z
      - ./config/20-config.mqsc:/etc/mqm/20-config.mqsc:ro,z
      - ./tls:/etc/mqm/tls:ro,z
    networks: [crrnet]

  london2:
    container_name: crr-london2
    hostname: london2
    image: ${MQ_IMAGE:-icr.io/ibm-messaging/mq:10.0.0.0-r2}
    platform: linux/amd64
    environment:
      LICENSE: "accept"
      MQ_QMGR_NAME: "CRRQM"
      MQ_NATIVE_HA: "true"
      MQ_NATIVE_HA_INSTANCE_NAME: "london2"
    volumes:
      - london2-data:/mnt/mqm
      - ./config/london2.ini:/etc/mqm/nativeha.ini:ro,z
      - ./config/20-config.mqsc:/etc/mqm/20-config.mqsc:ro,z
      - ./tls:/etc/mqm/tls:ro,z
    networks: [crrnet]

  london3:
    container_name: crr-london3
    hostname: london3
    image: ${MQ_IMAGE:-icr.io/ibm-messaging/mq:10.0.0.0-r2}
    platform: linux/amd64
    environment:
      LICENSE: "accept"
      MQ_QMGR_NAME: "CRRQM"
      MQ_NATIVE_HA: "true"
      MQ_NATIVE_HA_INSTANCE_NAME: "london3"
    volumes:
      - london3-data:/mnt/mqm
      - ./config/london3.ini:/etc/mqm/nativeha.ini:ro,z
      - ./config/20-config.mqsc:/etc/mqm/20-config.mqsc:ro,z
      - ./tls:/etc/mqm/tls:ro,z
    networks: [crrnet]

  rome1:
    container_name: crr-rome1
    hostname: rome1
    image: ${MQ_IMAGE:-icr.io/ibm-messaging/mq:10.0.0.0-r2}
    platform: linux/amd64
    environment:
      LICENSE: "accept"
      MQ_QMGR_NAME: "CRRQM"
      MQ_NATIVE_HA: "true"
      MQ_NATIVE_HA_INSTANCE_NAME: "rome1"
    volumes:
      - rome1-data:/mnt/mqm
      - ./config/rome1.ini:/etc/mqm/nativeha.ini:ro,z
      - ./config/20-config.mqsc:/etc/mqm/20-config.mqsc:ro,z
      - ./tls:/etc/mqm/tls:ro,z
    networks: [crrnet]

  rome2:
    container_name: crr-rome2
    hostname: rome2
    image: ${MQ_IMAGE:-icr.io/ibm-messaging/mq:10.0.0.0-r2}
    platform: linux/amd64
    environment:
      LICENSE: "accept"
      MQ_QMGR_NAME: "CRRQM"
      MQ_NATIVE_HA: "true"
      MQ_NATIVE_HA_INSTANCE_NAME: "rome2"
    volumes:
      - rome2-data:/mnt/mqm
      - ./config/rome2.ini:/etc/mqm/nativeha.ini:ro,z
      - ./config/20-config.mqsc:/etc/mqm/20-config.mqsc:ro,z
      - ./tls:/etc/mqm/tls:ro,z
    networks: [crrnet]

  rome3:
    container_name: crr-rome3
    hostname: rome3
    image: ${MQ_IMAGE:-icr.io/ibm-messaging/mq:10.0.0.0-r2}
    platform: linux/amd64
    environment:
      LICENSE: "accept"
      MQ_QMGR_NAME: "CRRQM"
      MQ_NATIVE_HA: "true"
      MQ_NATIVE_HA_INSTANCE_NAME: "rome3"
    volumes:
      - rome3-data:/mnt/mqm
      - ./config/rome3.ini:/etc/mqm/nativeha.ini:ro,z
      - ./config/20-config.mqsc:/etc/mqm/20-config.mqsc:ro,z
      - ./tls:/etc/mqm/tls:ro,z
    networks: [crrnet]

networks:
  crrnet:
    name: mq-crr-network

volumes:
  london1-data:
  london2-data:
  london3-data:
  rome1-data:
  rome2-data:
  rome3-data:

Valide o ficheiro Docker Compose :

docker compose config --quiet
docker compose pull

8. Inicie o grupo London Live

Se executou alguma versão anterior deste laboratório, execute o seguinte código. Ele remove todos os seis container de laboratório, seus volumes de dados do Queue Manager e quaisquer containers remanescentes.

docker compose down -v --remove-orphans

docker rm -f \
  crr-london1 crr-london2 crr-london3 \
  crr-rome1 crr-rome2 crr-rome3 \
  2>/dev/null || true

docker network rm mq-crr-network 2>/dev/null || true

A opção -v remove todas as mensagens e o estado de execuções prévias de Queue Managers. Use-a aqui de forma a fazer a reinicializarão do ambiente de laboratório.

Efetue novamente a geração dos seis ficheiros INI e valide. A segunda verificação deverá mostrar No host ports published:

./make-config.sh
docker compose config --quiet

if docker compose config | grep -q 'published:'; then
  echo "ERROR: remove every ports: section from docker-compose.yaml"
  docker compose config | grep -n -A 3 -B 2 'published:'
  exit 1
else
  echo "No host ports published"
fi

Esta verificação evita que um ficheiro Docker Compose mais antigo retenha mapeamentos como 1414:1414. O laboratório não requer nenhuma porta de host: a validação usa docker exec, enquanto Native HA e CRR usam a rede privada Docker.

Inicie o grupo London para que ele possa estabelecer o estado inicial dos Queue Managers:

docker compose up -d london1 london2 london3

Monitorize o processo de inicializarão:

docker compose logs --tail=40 london1 london2 london3

Confirme se os container ainda estão em execução:

docker compose ps -a london1 london2 london3

Em seguida, verifique o estado dos Queue Manager e o estado Native HA para cada instância.

for c in crr-london1 crr-london2 crr-london3; do
  echo "== $c =="
  docker exec "$c" dspmq -m CRRQM -o status
  docker exec "$c" dspmq -m CRRQM -o nativeha
done

Após a inicialização, espere obter um ROLE(Active), dois ROLE(Replica), QUORUM(3/3), GRPNAME(london) e GRPROLE(Live).

Guarde o nome do container ativo:

LONDON_ACTIVE=$(
  for c in crr-london1 crr-london2 crr-london3; do
    docker exec "$c" dspmq -m CRRQM -o nativeha | \
      grep -q 'ROLE(Active)' && echo "$c" && break
  done
)
echo "London active instance: $LONDON_ACTIVE"

Logo que LONDON_ACTIVE não esteja vazio, exiba os registos do grupo CRR local e remoto:

docker exec "$LONDON_ACTIVE" dspmq -m CRRQM -o nativeha -g

Confirme se a fila de teste existe:

printf 'DISPLAY QLOCAL(CRR.TEST.QUEUE) CURDEPTH DEFPSIST\n' | \
  docker exec -i "$LONDON_ACTIVE" runmqsc CRRQM

Se LONDON_ACTIVE estiver vazio, aguarde 20 segundos, repita o comando e inspecione a seção de solução de problemas abaixo.

9. Inicie o grupo de Recovery Rome

Inicie o segundo grupo:

docker compose up -d rome1 rome2 rome3

Verifique o seu estado:

for c in crr-rome1 crr-rome2 crr-rome3; do
  echo "== $c =="
  docker exec "$c" dspmq -m CRRQM -o status
  docker exec "$c" dspmq -m CRRQM -o nativeha
done

Aguarde até que uma instância de Rome mostre ROLE(Leader), as outras mostrem ROLE(Replica) e o grupo mostre GRPNAME(rome), GRPROLE(Recovery) e QUORUM(3/3).

A primeira sincronização pode demorar porque Rome deve estabelecer a sua cópia de recuperação. Repita este comando até que a conexão do grupo esteja normal:

docker exec "$LONDON_ACTIVE" dspmq -m CRRQM -o nativeha -g

A seção relacionada com o grupo de recuperação deverá eventualmente incluir valores equivalentes a:

GRPNAME(rome) GRPROLE(Recovery) CONNGRP(yes) GRSTATUS(Normal) BACKLOG(0) INSYNC(yes)

10. Confirme a replicação protegida por TLS

Procure nos logs do Queue Manager por ligações Native HA:

docker exec "$LONDON_ACTIVE" grep -E \
  'AMQ3305I|secure connection|certificate DN' \
  /var/mqm/qmgrs/CRRQM/errors/AMQERR01.LOG || true

Deverá ver mensagens referentes a ligações seguras e ao certificado DN CN=CRRQM-REPLICATION.

Se os dois grupos não conseguirem ligar-se entre si, inspecione todos os registos de erros recentes do MQ:

for c in crr-london1 crr-london2 crr-london3 crr-rome1 crr-rome2 crr-rome3; do
  echo "== $c =="
  docker exec "$c" tail -n 25 \
    /var/mqm/qmgrs/CRRQM/errors/AMQERR01.LOG 2>/dev/null || true
done

11. Coloque uma mensagem persistente em Londres

Coloque uma mensagem no Queue Manager Live:

printf 'Message written in London before the CRR switchover\n\n' | \
  docker exec -i "$LONDON_ACTIVE" /opt/mqm/samp/bin/amqsput CRR.TEST.QUEUE CRRQM

Verifique a sua profundidade:

printf 'DISPLAY QLOCAL(CRR.TEST.QUEUE) CURDEPTH\n' | \
  docker exec -i "$LONDON_ACTIVE" runmqsc CRRQM

Antes de mudar de função, confirme novamente se o estado de recuperação mostra BACKLOG(0) e INSYNC(yes):

docker exec "$LONDON_ACTIVE" dspmq -m CRRQM -o nativeha -g

O mecanismo CRR é assíncrono, portanto, uma colocação de mensagem bem-sucedida em London não prova por si só que Rome já possua o registro de log correspondente. BACKLOG(0) e INSYNC(yes) são verificações importantes antes de uma transição controlada.

12. Execute uma transição CRR planeada

Uma transição planeada coordena ambos os grupos e aguarda a sincronização dos logs de recuperação. Este processo é diferente de um failover de emergência, em que o site Live original não está disponível e pode existir alguma perda de dados ou risco de split brain.

Peça que London passe do estado Live para Recovery:

cat > set-role.sh <<'SCRIPT'
#!/usr/bin/env bash
set -euo pipefail

from_role=$1
to_role=$2
shift 2

for file in "$@"; do
  grep -q "GroupRole=$from_role" "$file" || {
    echo "$file does not request GroupRole=$from_role" >&2
    exit 1
  }
  sed "s/GroupRole=$from_role/GroupRole=$to_role/" "$file" > "$file.tmp"
  mv "$file.tmp" "$file"
done
SCRIPT

chmod +x set-role.sh
./set-role.sh Live Recovery \
  config/london1.ini config/london2.ini config/london3.ini
docker compose restart london1 london2 london3

Verifique o status de London até este mostrar uma transição de recuperação pendente:

for c in crr-london1 crr-london2 crr-london3; do
  docker exec "$c" dspmq -m CRRQM -o nativeha
done

Agora solicite que Rome assuma o estado Live:

./set-role.sh Recovery Live \
  config/rome1.ini config/rome2.ini config/rome3.ini
docker compose restart rome1 rome2 rome3

Durante o processo de coordenação, os grupos podem reportar Pending recovery e Pending live. Espere que Rome eleja uma instância ativa:

ROME_ACTIVE=""
for attempt in $(seq 1 30); do
  ROME_ACTIVE=$(
    for c in crr-rome1 crr-rome2 crr-rome3; do
      docker exec "$c" dspmq -m CRRQM -o nativeha | \
        grep -q 'ROLE(Active)' && echo "$c" && break
    done
  )
  [ -n "$ROME_ACTIVE" ] && break
  sleep 5
done
echo "Rome active instance: $ROME_ACTIVE"

Exiba o estado final do grupo:

docker exec "$ROME_ACTIVE" dspmq -m CRRQM -o nativeha -g

Rome deverá agora mostrar GRPROLE(Live) e London deverá mostrar GRPROLE(Recovery).

13. Prove que a mensagem foi propagada

Leia a mensagem do novo grupo Live:

docker exec -i "$ROME_ACTIVE" /opt/mqm/samp/bin/amqsget CRR.TEST.QUEUE CRRQM

A saída deve conter:

Message written in London before the CRR switchover

Isso demonstra que:

  1. London aceitou uma mensagem persistente.
  2. O Native HA efetuou a proteção dentro do grupo London.
  3. O CRR copiou de forma assíncrona o log de recuperação correspondente para Rome.
  4. A transição planeada sincronizou os grupos antes da troca de funções.
  5. Rome ativou o mesmo Queue Manager e expôs a mensagem.

14. Volte para London (estado inicial)

Para restaurar as funções originais, primeiro solicite que o grupo Live atual, Rome, se torne Recovery:

./set-role.sh Live Recovery \
  config/rome1.ini config/rome2.ini config/rome3.ini
docker compose restart rome1 rome2 rome3

Em seguida, solicite que London se torne Live:

./set-role.sh Recovery Live \
  config/london1.ini config/london2.ini config/london3.ini
docker compose restart london1 london2 london3

Monitore ambos os grupos até que London tenha novamente uma instância ROLE(Active) e Rome tenha uma instância ROLE(Leader):

for c in crr-london1 crr-london2 crr-london3 crr-rome1 crr-rome2 crr-rome3; do
  echo "== $c =="
  docker exec "$c" dspmq -m CRRQM -o nativeha
done

15. Por que é que este laboratório não força um failover não planeado

Um failover CRR não planeado é uma decisão de recuperação de desastres, não simplesmente outra reinicialização de containers. Se o grupo Live estiver inacessível, o grupo Recovery não poderá provar que possui todos os registros de log finais ou que o grupo antigo permanecerá parado. Forçar o grupo de recuperação Live pode, portanto, introduzir:

  • um ponto de recuperação diferente de zero
  • perda de mensagens que existiam apenas no site com falha
  • duas cópias independentemente ativas do mesmo Queue Manager
  • dados particionados ou situação de Split Brain que devem ser resolvidos posteriormente

O que podemos fazer de forma segura num ambiente com um mesmo Host é a transição planeada acima. Estude os procedimentos de failover não planeado e de Split Brain como documentados pela IBM antes de testar a promoção forçada e use domínios de falha separados ao fazer isso.

16. Solução de problemas

O comando de status -g não mostra nada

A saída dspmq -o nativeha -g de nível de grupo fica vazia quando MQ não considera o Queue Manager como parte de um grupo Native HA. Execute estas verificações sem redirecionar a saída de erros:

docker compose ps -a london1 london2 london3

for c in crr-london1 crr-london2 crr-london3; do
  echo "== $c: MQ status =="
  docker exec "$c" dspmq -m CRRQM -o status
  docker exec "$c" dspmq -m CRRQM -o nativeha
done

Se a saída em nível de instância indicar ROLE(Not configured), verifique o que é que o primeiro container recebeu e o que é que o MQ aplicou:

docker inspect crr-london1 \
  --format '{{range .Config.Env}}{{println .}}{{end}}' | grep '^MQ_'

docker exec crr-london1 cat /etc/mqm/nativeha.ini
docker exec crr-london1 grep -n -A12 -E \
  '^NativeHA(LocalInstance|Instance|RecoveryGroup):' \
  /var/mqm/qmgrs/CRRQM/qm.ini

docker compose logs --tail=150 london1 london2 london3

Não prossiga para Rome até que os três comandos em nível de instância de London mostrem um ROLE(Active), dois ROLE(Replica) e quórum. Se esses container tiverem sido inicializados antes que a configuração Native HA esteja correta, use o procedimento de cleanup abaixo para recriar os volumes de dados.

Um container termina durante a inicialização

Verifique sos logs:

docker compose ps -a
docker compose logs --tail=100 london1

As causas comuns incluem memória insuficiente, um keystore ilegível, um ficheiro INI malformado ou reutilização de volumes de dados criados com configurações diferentes.

Os grupos permanecem desconectados

Confirme se o DNS do Docker resolve todos os seis nomes de serviço:

docker exec crr-london1 getent hosts rome1 rome2 rome3
docker exec crr-rome1 getent hosts london1 london2 london3

Confirme se os ficheiros TLS estão visíveis:

docker exec crr-london1 find /etc/mqm/tls -maxdepth 1 \
  -name 'keystore.*' -ls
docker exec crr-rome1 find /etc/mqm/tls -maxdepth 1 \
  -name 'keystore.*' -ls

Em seguida, inspecione AMQERR01.LOG nos líderes do grupo em busca de certificados, CipherSpec ou erros de conexão.

Um grupo não atinge o quórum

Todos os três membros desse grupo devem estar em execução e capazes de resolver uns aos outros na porta 9414:

docker compose ps
docker exec crr-london1 getent hosts london2 london3

Uma mudança de função não entra em vigor

Verifique se todos os três ficheiros INI no grupo solicitam a mesma função:

grep GroupRole config/*.ini

O role a assumir é uma decisão de grupo. A maioria deve solicitar a mesma transição e os dois grupos devem coordenar-se para uma transição planeada.

Comece novamente a partir de um estado limpo

Se este for um laboratório descartável e os dados de inicialização forem inconsistentes, remova os container e volumes antes de tentar novamente:

docker compose down -v --remove-orphans
docker rm -f \
  crr-london1 crr-london2 crr-london3 \
  crr-rome1 crr-rome2 crr-rome3 \
  2>/dev/null || true
docker network rm mq-crr-network 2>/dev/null || true

./make-config.sh
docker compose config --quiet
docker compose config | grep -q 'published:' && {
  echo "ERROR: remove every ports: section from docker-compose.yaml"
  exit 1
}

docker compose up -d london1 london2 london3
docker compose ps -a

Use down -v somente quando desejar excluir intencionalmente todos os dados dos Queue Manager. Todos os três container de London devem apresentar Up.

17. O que o laboratório demonstra

Native HA e CRR resolvem problemas relacionados, mas diferentes:

CamadaReplicaçãoObjetivo principalTransição
Native HA dentro de London ou RomeSíncronoSobreviver a uma instância ou falha de armazenamento localEleição automática de líder
CRR entre London e RomeAssíncronoRecuperar o Queue Manager em outra regiãoMudança de função controlada pelo operador

O grupo de recuperação não é um segundo Queue Manager. É uma cópia protegida do mesmo Queue Manager lógico, mantida a partir de dados de log de recuperação e promovida por meio de uma transição de função controlada.

A infraestrutura de uma única VM torna essa mecânica visível, mas um design real deve distribuir as seis instâncias em duas regiões, isolar domínios de falha para storage e rede, dimensionar o local de recuperação de forma a suportar a carga total de produção, expor endpoints estáveis para clientes, automatizar a monitorização e ensaiar procedimentos planeados e não planeados.

18. Procedimento de limpeza

Remova todos os seis containers, a rede Docker e os volumes dos Queue Manager:

docker compose down -v

Remova os ficheiros do laboratório:

cd "$HOME"
rm -rf "$HOME/mq-crr-lab"

A imagem IBM MQ permanece no cache de imagens local. Remova-a apenas se não precisar mais dela:

docker image rm icr.io/ibm-messaging/mq:10.0.0.0-r2

Apêndice A. Instalação do Docker e Docker Compose

Docker Linux Engine

Identifique a distribuição Linux antes de escolher as instruções de instalação:

. /etc/os-release
echo "$ID $VERSION_ID"

No Ubuntu ou Debian, use o repositório oficial APT do Docker. Os repositórios das distribuições Linux não fornecem de forma consistente o docker-compose-plugin.

(
set -e

. /etc/os-release
case "$ID" in
  ubuntu)
    DOCKER_DIST=ubuntu
    DOCKER_CODENAME=${UBUNTU_CODENAME:-$VERSION_CODENAME}
    ;;
  debian)
    DOCKER_DIST=debian
    DOCKER_CODENAME=$VERSION_CODENAME
    ;;
  *)
    echo "This APT block supports Ubuntu and Debian, not $ID."
    exit 1
    ;;
esac

sudo apt-get update
sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL "https://download.docker.com/linux/$DOCKER_DIST/gpg" \
  -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

ARCH=$(dpkg --print-architecture)
sudo tee /etc/apt/sources.list.d/docker.sources >/dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/$DOCKER_DIST
Suites: $DOCKER_CODENAME
Components: stable
Architectures: $ARCH
Signed-By: /etc/apt/keyrings/docker.asc
EOF

sudo apt-get update
apt-cache policy docker-ce docker-compose-plugin
sudo apt-get install -y \
  docker-ce \
  docker-ce-cli \
  containerd.io \
  docker-buildx-plugin \
  docker-compose-plugin

sudo systemctl enable --now docker
)

Os parênteses executam a instalação em um sub-shell. O set -e interrompe a instalação se um comando falhar, em vez de continuar para systemctl e produzir a mensagem Unit file docker.service does not exist. Ele não deixa o modo de saída de erro ativado no seu shell interativo. Para outras distribuições Linux, siga as instruções de instalação do Docker para essa distribuições em vez de adaptar os comandos APT.

Se o seu usuário Linux não tiver permissão para aceder o Docker, adicione-o ao grupo docker:

sudo usermod -aG docker "$USER"
newgrp docker

Verifique as ferramentas:

docker version
docker compose version
uname -m

O Linux VM deve reportar x86_64.

Docker Desktop no macOS

Instale o Docker Desktop. O Docker Desktop já inclui Docker Engine, Docker CLI e Compose v2.

No Apple Silicon, abra Docker Desktop > Configurações > Geral:

  1. Selecione Apple Virtualization Framework como gestor de máquina virtual.
  2. Ative Usar Rosetta para emulação x86_64/amd64 no Apple Silicon.

Em Configurações > Recursos, atribua pelo menos 12 GB RAM. Aplique as alterações e reinicie o Docker Desktop.

Verifique Docker, Compose, inicialização do container AMD64 e docker exec:

docker version
docker compose version
docker run --rm --platform linux/amd64 alpine:3.21 uname -m
docker run -d --name amd64-exec-test --platform linux/amd64 alpine:3.21 sleep 60
docker exec amd64-exec-test uname -m
docker rm -f amd64-exec-test

Ambos os comandos devem retornar x86_64. Se a inicialização do container ou docker exec retornar exec format error, verifique novamente o gestor de máquina virtual Docker Desktop e a configuração do Rosetta antes de iniciar o laboratório MQ.

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