As streaming queues do IBM MQ permitem que um queue manager coloque uma cópia quase idêntica de cada mensagem numa segunda fila. A aplicação que faz put na fila original não precisa de mudar, e a aplicação que faz get da fila original continua sem saber que o streaming ocorreu.
Este artigo é deliberadamente prático. Usa um único container IBM MQ, cria um pequeno conjunto de filas locais e valida depois os dois modos de qualidade de serviço de streaming (BESTEF e MUSTDUP):
Também introduz CAPEXPRY, que é importante quando quer reter as mensagens duplicadas por um período limitado em vez de deixar a fila de destino crescer indefinidamente.
1. Objetivos do lab
No final deste lab deverá ser capaz de:
- Explicar o objetivo e funcionamiento de streaming queues do IBM MQ
- Configurar
STREAMQeSTRMQOSem filas locais - Entender a diferença entre
BESTEFeMUSTDUP - Compreender porque
CAPEXPRYé importante na fila de destino - Reconhecer as principais restrições que se aplicam a streaming queues
2. Software necessário
Para este lab, vamos usar:
- IBM MQ
9.4.xem Linux - Docker Engine e plugin Docker Compose
- uma conta Linux com permissões para executar comandos Docker
Se o Docker ainda não estiver instalado, execute:
- Ubuntu / Debian
sudo apt-get update
sudo apt-get install -y docker.io docker-compose-plugin
sudo systemctl enable --now docker- RHEL / CentOS / Fedora
sudo dnf -y install dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now dockerVerifique a instalação:
docker version
docker compose versionObtenha a imagem de IBM MQ:
docker pull icr.io/ibm-messaging/mq:latest3. O que as streaming queues acrescentam a um desenho MQ
As streaming queues são configuradas nas propriedades das filas, e não nas aplicações. Os atributos a considerar são:
| Atributo | Finalidade |
|---|---|
STREAMQ | Indica a segunda fila que recebe a mensagem duplicada |
STRMQOS(BESTEF) | Preserva o fluxo da mensagem original mesmo que a duplicada não possa ser entregue |
STRMQOS(MUSTDUP) | Exige que a mensagem original e a duplicada sejam ambas entregues com sucesso |
CAPEXPRY | Limita a expiração das mensagens que chegam à fila de destino do streaming |
A decisão principal a tomar costuma ser esta:
- Se o fluxo de negócio original tiver de continuar mesmo quando o caminho duplicado tiver problemas, use
BESTEF - Se a cópia duplicada for obrigatória, por exemplo por compliance ou por captura garantida para replay, use
MUSTDUP
4. Comportamento operacional importante
Dois detalhes que é importante saber:
1. A mensagem duplicada é criada pelo queue manager, não pela aplicação que faz put 2. Quando o MQ faz streaming de uma mensagem, a cópia duplicada tem a sua expiração redefinida para ilimitada, exceto se a restringir com CAPEXPRY na fila que recebe a cópia
Este segundo ponto é fácil de ignorar. Se fizer streaming para uma fila de histórico e ninguém a consumir, essa fila continuará a crescer sem controlo.
5. Principais restrições a ter em conta
Existem algumas restrições importantes do mecanismo de streaming:
- Não é possível criar cadeias de streaming como
Q1 -> Q2,Q2 -> Q3 - Não é possível criar ciclos como
Q1 -> Q2,Q2 -> Q1 - Não é possível definir
STREAMQnuma transmission queue STREAMQnão pode referir uma queue model.
Por motivos de simplicidade, este lab usa apenas filas locais num único queue manager.
6. Criar a pasta do lab e o ficheiro docker-compose
Crie uma pasta de trabalho:
mkdir -p ~/mq-streaming-lab
cd ~/mq-streaming-labCrie o ficheiro docker-compose.yaml:
cat > docker-compose.yaml <<'EOF'
services:
mq-dev:
container_name: mq-dev
image: icr.io/ibm-messaging/mq:latest
environment:
LICENSE: "accept"
MQ_QMGR_NAME: "QM1"
ports:
- "1414:1414"
EOF7. Iniciar o queue manager
Inicie o container docker:
docker compose up -dConfirme que o queue manager está ativo:
docker exec mq-dev dspmqDeverá ver QM1 em estado Running.
8. Criar as filas do lab
Este bloco de código cria as seguintes filas:
APP.IN.NORMALpara um exemplo normal de streamingAPP.IN.BESTpara o cenárioBESTEFAPP.IN.MUSTpara o cenárioMUSTDUPAPP.AUDITcomo fila duplicada normalAPP.AUDIT.SMALLcomo fila duplicada deliberadamente limitada
docker exec -i mq-dev runmqsc QM1 <<'EOF'
DEFINE QLOCAL(APP.IN.NORMAL) REPLACE
DEFINE QLOCAL(APP.IN.BEST) REPLACE
DEFINE QLOCAL(APP.IN.MUST) REPLACE
DEFINE QLOCAL(APP.AUDIT) REPLACE
DEFINE QLOCAL(APP.AUDIT.SMALL) MAXDEPTH(1) REPLACE
CLEAR QLOCAL(APP.IN.NORMAL)
CLEAR QLOCAL(APP.IN.BEST)
CLEAR QLOCAL(APP.IN.MUST)
CLEAR QLOCAL(APP.AUDIT)
CLEAR QLOCAL(APP.AUDIT.SMALL)
END
EOFConfirme as definições:
docker exec -i mq-dev runmqsc QM1 <<'EOF'
DISPLAY QLOCAL(APP.IN.NORMAL) STREAMQ STRMQOS
DISPLAY QLOCAL(APP.IN.BEST) STREAMQ STRMQOS
DISPLAY QLOCAL(APP.IN.MUST) STREAMQ STRMQOS
DISPLAY QLOCAL(APP.AUDIT) CURDEPTH MAXDEPTH CAPEXPRY
DISPLAY QLOCAL(APP.AUDIT.SMALL) CURDEPTH MAXDEPTH CAPEXPRY
END
EOF9. Streaming básico com BESTEF
Ative o streaming de APP.IN.NORMAL para APP.AUDIT:
docker exec -i mq-dev runmqsc QM1 <<'EOF'
ALTER QLOCAL(APP.IN.NORMAL) STREAMQ(APP.AUDIT) STRMQOS(BESTEF)
CLEAR QLOCAL(APP.IN.NORMAL)
CLEAR QLOCAL(APP.AUDIT)
DISPLAY QLOCAL(APP.IN.NORMAL) STREAMQ STRMQOS
END
EOFColoque uma mensagem:
docker exec mq-dev bash -lc "printf 'stream-normal-1\n' | /opt/mqm/samp/bin/amqsput APP.IN.NORMAL QM1"Examine a fila original:
docker exec mq-dev /opt/mqm/samp/bin/amqsbcg APP.IN.NORMAL QM1Examine a fila duplicada:
docker exec mq-dev /opt/mqm/samp/bin/amqsbcg APP.AUDIT QM1Neste ponto deverá ver o mesmo conteúdo em ambas as filas.
10. Comportamento BESTEF quando a fila duplicada já está cheia
Vamos agora criar um cenário em que a fila de destino do streaming não consiga receber mais mensagens e o caminho original deva continuar a funcionar.
Configure APP.IN.BEST para fazer streaming para a fila pequena:
docker exec -i mq-dev runmqsc QM1 <<'EOF'
ALTER QLOCAL(APP.IN.BEST) STREAMQ(APP.AUDIT.SMALL) STRMQOS(BESTEF)
CLEAR QLOCAL(APP.IN.BEST)
CLEAR QLOCAL(APP.AUDIT.SMALL)
END
EOFColoque uma mensagem em APP.AUDIT.SMALL para atingir MAXDEPTH(1):
docker exec mq-dev bash -lc "printf 'pre-fill-small-queue\n' | /opt/mqm/samp/bin/amqsput APP.AUDIT.SMALL QM1"Verifique a profundidade da fila:
docker exec -i mq-dev runmqsc QM1 <<'EOF'
DISPLAY QLOCAL(APP.AUDIT.SMALL) CURDEPTH MAXDEPTH
END
EOFColoque agora uma mensagem na fila original configurada com BESTEF:
docker exec mq-dev bash -lc "printf 'best-effort-message\n' | /opt/mqm/samp/bin/amqsput APP.IN.BEST QM1"Verifique a profundidade de ambas as filas:
docker exec -i mq-dev runmqsc QM1 <<'EOF'
DISPLAY QLOCAL(APP.IN.BEST) CURDEPTH
DISPLAY QLOCAL(APP.AUDIT.SMALL) CURDEPTH
END
EOFInterpretação:
APP.IN.BESTdeverá conter a mensagem originalAPP.AUDIT.SMALLdeverá continuar cheia apenas com a mensagem pré-carregada
Isto é exatamente o significado de BESTEF: o caminho da mensagem original continua disponível mesmo que a cópia duplicada não possa ser entregue.
11. Comportamento MUSTDUP quando a fila duplicada já está cheia
Agora passamos ao modo mais restritivo. Configure APP.IN.MUST para fazer streaming para a mesma fila (a que tem profundidade limitada a um máximo de 1 mensagem):
docker exec -i mq-dev runmqsc QM1 <<'EOF'
ALTER QLOCAL(APP.IN.MUST) STREAMQ(APP.AUDIT.SMALL) STRMQOS(MUSTDUP)
CLEAR QLOCAL(APP.IN.MUST)
DISPLAY QLOCAL(APP.IN.MUST) STREAMQ STRMQOS
END
EOFMantendo APP.AUDIT.SMALL cheia, tente colocar uma nova mensagem:
docker exec mq-dev bash -lc "set -o pipefail; printf 'must-duplicate-message\n' | /opt/mqm/samp/bin/amqsput APP.IN.MUST QM1; echo RC:$?"Verifique de novo as filas:
docker exec -i mq-dev runmqsc QM1 <<'EOF'
DISPLAY QLOCAL(APP.IN.MUST) CURDEPTH
DISPLAY QLOCAL(APP.AUDIT.SMALL) CURDEPTH
END
EOF- O
putdeverá falhar porque a fila duplicada não consegue aceitar a cópia APP.IN.MUSTdeverá continuar vaziaAPP.AUDIT.SMALLdeverá manter profundidade1
Esta é a diferença operacional que mais importa na prática:
BESTEFprotege o fluxo da aplicação originalMUSTDUPprotege a garantia de que existe uma cópia duplicada
12. Aplicar retenção com CAPEXPRY
Se fizer streaming para uma fila de histórico e ninguém a consumir, as mensagens acumulam-se. Uma prática comum é usar CAPEXPRY para limitar o tempo de vida da cópia duplicada.
Defina CAPEXPRY na fila de destino:
docker exec -i mq-dev runmqsc QM1 <<'EOF'
ALTER QLOCAL(APP.AUDIT) CAPEXPRY(300)
DISPLAY QLOCAL(APP.AUDIT) CAPEXPRY
END
EOFIsto significa que novas mensagens a chegar a APP.AUDIT não poderão viver mais do que 300 segundos, mesmo que a cópia duplicada tivesse, de outra forma, expiração ilimitada.
Num cenário de produção, isto é por vezes preferível a criar uma aplicação separada apenas para limpar a fila de histórico.
13. O que o lab mostrou
Este lab demonstrou quatro pontos concretos:
1. As streaming queues são configuradas em objetos fila, não na aplicação que faz put. 2. O queue manager coloca uma cópia quase idêntica da mensagem na fila secundária. 3. BESTEF e MUSTDUP são materialmente diferentes quando o caminho duplicado tem um problema. 4. CAPEXPRY é importante para controlar a retenção na fila de destino.
14. Quando streaming queues são uma boa opção
As streaming queues são especialmente úteis quando precisa de:
- Um histórico de curto prazo de mensagens de negócio
- Uma alimentação duplicada para análise ou observabilidade
- Uma origem de replay para testes de recuperação
- Um mecanismo pouco intrusivo para copiar mensagens para outro fluxo de processamento
Serão menos adequadas quando precisa de fan-out complexo ou lógica de transformação. Nesses casos, uso de publish/subscribe ou uma camada adicional de integração serão provavelmente uma melhor escolha.
15. Resumo
As streaming queues do IBM MQ são deliberadamente simples: configure uma fila de origem com STREAMQ, escolha BESTEF ou MUSTDUP, e deixe o queue manager duplicar as mensagens.
A pergunta prática a ter em conta no desenho da solução não é se o streaming funciona, mas que fazer em caso de falha:
- Se o caminho de negócio original tiver de permanecer isolado de falhas no caminho duplicado, use
BESTEF - Se a cópia duplicada for obrigatória, use
MUSTDUP
Se necessário, use CAPEXPRY para controlar a retenção de mensagens na fila de destino.
16. Cleanup
Este passo de cleanup remove apenas os artefactos do lab. Não desinstala Docker nem IBM MQ do host.
docker compose down -v
cd ..
rm -rf ~/mq-streaming-lab