Pyxis Logo
Inicio / Formación IBM / Artículo técnico

Alta disponibilidad nativa (Native HA) en Docker: Resiliencia Cloud-Native

Cómo configurar IBM MQ Native HA utilizando Docker, volúmenes de configuración y demostrar el ACR (Automatic Client Reconnect) con un nodo de cliente dedicado.

20 min de lectura
Publicado 2026-05-14
Pyxis editorial team
Califique este artículo
Calificación media: Sin calificación
Su calificación: Sin calificación
visualizaciones: 0
Diagrama de tres contenedores MQ en replicación síncrona

Históricamente, la Alta Disponibilidad (HA) en IBM MQ dependía de almacenamiento compartido o de replicación externa (RDQM). En las arquitecturas modernas de microservicios y nube (Kubernetes, OpenShift, Docker), el almacenamiento compartido introduce complejidad y latencia.

El Native HA utiliza un algoritmo de consenso (Raft) para replicar datos entre tres instancias independientes. Este laboratorio demuestra cómo levantar un clúster resiliente de 3 nodos usando Docker Compose, utilizando archivos de configuración (qm.ini) montados mediante volúmenes para garantizar el 100 % de fiabilidad en la versión 9.4+. Además, demostraremos el Automatic Client Reconnect (ACR) utilizando un cuarto nodo como cliente.

¿Cómo funciona MQ Native HA?

MQ Native HA fue diseñado para eliminar la dependencia de las tecnologías de almacenamiento compartido (como NFS o SAN), que son frecuentemente complejas y lentas en entornos de nube.

1. El protocolo Raft y el quórum

Native HA se basa en el algoritmo de consenso Raft. En un grupo de tres instancias, los nodos se comunican continuamente para elegir un Líder (Active). Las otras dos instancias se convierten en Réplicas.

  • Quórum: Para que el clúster acepte mensajes, la mayoría de los nodos (2 de 3) debe estar funcional y en comunicación. Esto evita el "Split-brain", donde dos nodos podrían intentar ser activos simultáneamente, corrompiendo los datos.
  • Elección automática: Si el Líder falla, las Réplicas detectan la ausencia de "heartbeats" e inician una nueva elección. El nodo con el registro de recuperación más actualizado es elegido como nuevo Líder.

2. Replicación síncrona

A diferencia de otras soluciones, MQ Native HA replica los datos al nivel del registro de recuperación. Cuando una aplicación envía un mensaje persistente: 1. El Líder escribe el mensaje en su registro local. 2. El Líder envía los datos del registro a las Réplicas. 3. En cuanto al menos una Réplica confirma la recepción (garantizando la mayoría), el Líder confirma el éxito a la aplicación.

3. Limitaciones y comportamiento de las réplicas

Es fundamental comprender que las Réplicas no son "nodos activos de lectura". Existen limitaciones operativas estrictas:

  • Estado de Standby: Las Réplicas están en un estado de "espera en caliente". No procesan mensajes ni permiten que las aplicaciones se conecten a ellas (vía canales o localmente).
  • Sin conectividad de aplicación: Si intenta conectar una aplicación a una Réplica, recibirá el error "Queue Manager Not Available" (MQRC_Q_MGR_NOT_AVAILABLE).
  • Administración limitada: Comandos como runmqsc tienen una funcionalidad muy restringida en las Réplicas, sirviendo únicamente para consultar el estado del HA.

4. Automatic Client Reconnect (ACR)

El Automatic Client Reconnect (ACR) es una funcionalidad de las bibliotecas del cliente IBM MQ que permite la resiliencia transparente del lado de la aplicación.

Cómo funciona:

  • Transparencia: Si la conexión se interrumpe, el cliente MQ suspende la operación de la aplicación en lugar de devolver un error inmediato.
  • Reintento automático: El cliente MQ consulta la lista de nombres de conexión (CONNAME) configurada e intenta restablecer la sesión con los otros nodos.
  • Failover en Native HA: En un clúster Native HA, el cliente intentará conectarse a las Réplicas (que rechazarán la conexión) hasta encontrar el nuevo Líder (Active). Una vez conectado, el procesamiento se reanuda automáticamente, preservando la integridad de los mensajes.

Qué ocurre técnicamente en el cliente MQI:

  • Conexión elegible para reconexión: El cliente debe usar transporte client y una lista de direcciones alternativas, normalmente mediante CONNAME, CCDT, MQSERVER o mqclient.ini.
  • Reconexión inline: Cuando se detecta el fallo, el cliente intenta restablecer la conexión sin obligar a la aplicación a ejecutar un nuevo MQCONN o MQCONNX.
  • Restauración de contexto: Si la reconexión tiene éxito, los handles de conexión y de objetos son recreados por el cliente. Para muchas aplicaciones MQI, esto significa la reanudación del procesamiento con un impacto mínimo.
  • Espera más larga durante la llamada MQI: Si el fallo se produce en medio de una llamada, la aplicación puede observar únicamente una espera prolongada hasta que la operación termine o falle definitivamente.
  • No todas las APIs se comportan igual: En este laboratorio utilizaremos amqsphac, un sample de IBM MQ diseñado específicamente para demostrar la reconexión automática en escenarios de alta disponibilidad. El sample usa MQCNO_RECONNECT en el MQCONNX y mantiene el bucle de la aplicación activo durante la reconexión — algo que los samples genéricos como amqsputc no hacen. El ACR en sentido MQI no está soportado por las IBM MQ classes for Java; para JMS existe un mecanismo propio de reconexión automática.

Anatomía de la configuración (qm.ini)

La configuración lógica de Native HA reside en las stanzas NativeHALocalInstance y NativeHAInstance, que forman parte de la configuración del queue manager. En instalaciones Linux convencionales, esto significa editar el qm.ini de cada instancia.

En este laboratorio con contenedores, mantendremos esas stanzas en archivos dedicados node1.ini, node2.ini y node3.ini, montados como /etc/mqm/nativeha.ini. Lo importante es el contenido de las stanzas, no el nombre del archivo en el host. La imagen del contenedor consume ese archivo montado para inicializar la configuración de Native HA.

La configuración se divide en dos secciones principales:

NativeHALocalInstance

Define la identidad del nodo actual.

  • Name: El nombre único de esta instancia (ej: node1).

NativeHAInstance

Define todos los miembros que participan en el grupo HA. Debe haber una entrada para cada uno de los 3 nodos.

  • Name: Nombre único de la instancia.
  • ReplicationAddress: La dirección IP o nombre de host y el puerto dedicado exclusivamente al tráfico de replicación de Raft.

Lo que construye este laboratorio

Al final de este laboratorio, tendrá:

  • Un clúster de 3 contenedores MQ comunicándose a través de la red de Docker.
  • Configuración basada en archivos con stanzas equivalentes a qm.ini, simulando despliegues empresariales.
  • Un nodo de Cliente dedicado que demuestra la reconexión automática (ACR).
  • Replicación síncrona de registros sin necesidad de almacenamiento compartido.

Preparación del entorno: Instalación del software

Antes de comenzar el laboratorio, debe asegurarse de tener las herramientas de contenedores necesarias y acceso a la imagen oficial de MQ.

También necesita una de estas dos condiciones en el host Linux:

  • acceso a sudo
  • o pertenencia al grupo docker, para ejecutar Docker sin sudo

Si no dispone de ninguna de estas opciones, no podrá ejecutar este laboratorio tal como está descrito.

1. Instalar Docker y Docker Compose

Docker es la plataforma base para este laboratorio. Docker Compose permite orquestar los 3 nodos MQ de forma sencilla.

  • Windows/macOS: Instale Docker Desktop. Docker Compose ya viene incluido.
  • 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 la instalación:

docker version
docker compose version

Configuración de permisos (Linux)

Si recibe un error de "permiso denegado" al ejecutar comandos de Docker, su usuario debe añadirse al grupo docker:

sudo usermod -aG docker $USER

Nota: Debe ejecutar sudo newgrp docker o cerrar sesión y volver a entrar para aplicar los cambios.

Si prefiere no modificar todavía los grupos del sistema, puede simplemente ejecutar los comandos de este laboratorio con sudo, tal como ya aparecen en los bloques ejecutados en el host.

Confirme antes de continuar:

docker version

Si este comando falla y tampoco puede obtener acceso al grupo docker, deténgase aquí y resuelva primero el acceso al daemon de Docker.

2. Obtener la imagen de IBM MQ

Basta con ejecutar el comando:

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

1. Crear los archivos de configuración

Nodos MQ (.ini)

Crearemos tres archivos de configuración distintos para cada nodo.

Cree el archivo para el 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

Cree el archivo para el 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

Cree el archivo para el 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

Archivo de configuración MQ (config.mqsc)

Cree el archivo con toda la configuración de seguridad y cola. La imagen Docker de IBM MQ ejecuta automáticamente los archivos .mqsc montados en /etc/mqm/ al arrancar el nodo activo — las réplicas reciben la misma configuración por replicación 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. El archivo de orquestación (Clúster + Cliente)

Recree el archivo:

rm -f docker-compose.yaml

Después, abra el archivo:

vi docker-compose.yaml

Y pegue exactamente este contenido:

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 el clúster

Inicie los contenedores:

docker compose down -v
docker compose up -d

Espere unos segundos y confirme que el clúster está estable y que el archivo config.mqsc fue 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

Lo esperado es observar un nodo con ROLE(Active) y los otros dos con ROLE(Replica). Si los contenedores aún se están inicializando, espere unos segundos más y repita.

Identifique el nodo activo y confirme que la cola y el canal fueron creados automáticamente por el 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. Prueba de quórum y replicación síncrona

En esta primera fase, vamos a demostrar que el clúster sobrevive y mantiene los datos consistentes internamente.

Paso 1: Colocar un mensaje en el Líder

Identifique cuál es el nodo activo y guárdelo en una variable:

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"

Después, coloque un mensaje en ese nodo:

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

Escriba: "Validando replicación síncrona" y pulse Enter dos veces.

Paso 2: Simular un fallo (Stop Container)

Detenga el contenedor que está activo:

docker stop "$ACTIVE_NODE"

Paso 3: Verificar la elección y la consistencia

Compruebe quién es el nuevo líder y guárdelo en una variable:

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 allí el mensaje:

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

El éxito demuestra que el mensaje fue replicado al registro local del nuevo líder antes de la caída del nodo originalmente activo.

5. Demostración de ACR (Automatic Client Reconnect)

Ahora que hemos validado el backend, vamos a probar la resiliencia del lado de la aplicación con el sample amqsphac, que usa MQCNO_RECONNECT internamente y mantiene el bucle de envío activo durante y después del failover.

Paso 1: Garantizar que el clúster está operativo

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"

Paso 2: Crear el script de arranque del sample

Escriba el script línea a línea para evitar problemas con el pegado de comandos multilínea:

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'

Paso 3: Iniciar el sample en segundo plano

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

El amqsphac no produce salida línea a línea en modo no interactivo (buffering de stdout), por lo que la verificación se realiza mediante la profundidad de la cola. Confirme que los mensajes están llegando al nodo activo:

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

El CURDEPTH debe estar creciendo continuamente.

Paso 4: Provocar el fallo del nodo activo

docker stop "$ACTIVE_NODE"

Paso 5: Verificar la elección del nuevo 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"

Paso 6: Confirmar la reconexión automática mediante el crecimiento de la cola

Espere unos 10 segundos para que la elección se complete y verifique el CURDEPTH en el nuevo líder:

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

Si el CURDEPTH está creciendo en el nuevo líder, el amqsphac se reconectó automáticamente sin ninguna intervención — el ACR funcionó.

Paso 7: Confirmar los mensajes recibidos

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

Conclusiones clave para Docker

  • Resiliencia por capas: Validamos primero la replicación de datos y después la continuidad de la aplicación.
  • ACR & Native HA: La combinación perfecta para arquitecturas de alta disponibilidad total. El amqsphac usa MQCNO_RECONNECT para demostrar la reconexión transparente que una aplicación real debe implementar.
  • Configuración robusta: El uso de volúmenes para montar las stanzas de configuración de Native HA es el enfoque más fiable.

Cleanup

Al final del laboratorio, puede eliminar los contenedores y los archivos creados durante la práctica:

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

Este cleanup no desinstala Docker, Docker Compose ni la imagen de IBM MQ. Solo elimina los artefactos locales utilizados en este laboratorio.

Documentación útil

Más en esta área

Más en esta área

Volver a formación
Categoría de artículos

Artículos de IBM MQ

Consulta todos los artículos técnicos de IBM MQ en una sola página de categoría.

Abrir categoría IBM MQ