Noções básicas práticas do IBM MQ

Descritor de mensagem (MQMD) (1)

*Esta série pode ser revisada com base no último mqpgf/mqpcf. Por favor, baixe sempre e use a versão mais recente.

Nesta série, explicaremos os conceitos básicos do WebSphere MQ/IBM MQ através da verificação funcional do IBM MQ usando mqpgf/mqpcf que é o Software criado/fornecido por nós.

mqpgf é um programa que pode realizar vários testes usando MQI, APIs fornecidas pelo MQ. Ele interage com o gerenciador de filas através do processo do agente qmgr.

Fig. 1.1

mqpcf é um programa que pode enviar e receber comandos PCF com o servidor de comando usando MQAI, uma API de gerenciamento MQ, executar operações em objetos MQ e verificar seu status.

Fig. 1.2

Consulte o Guia do Usuário do mqpgf, o Guia do Usuário do mqpcf e o Centro de Conhecimento do MQ, conforme necessário. mqpgf / mqpcf pode ser baixado deste site, não há instalação, e é necessário apenas extrair o arquivo baixado e copiar o comando. Para obter detalhes, consulte os documentos incluídos no arquivo baixado. A instalação do MQ não será descrita nesta série, portanto, consulte o manual do produto. Mesmo que você não tenha uma licença para o IBM MQ, é possível usar o “Free Evaluation (90 days)” e o “WebSphere MQ Advanced for development” sob determinadas condições. Esta série é confirmada principalmente pelo MQ 9.x e MQ8.x, mas com o MQ 5.3 ou posterior, deve ser possível executar sem problemas, exceto para algumas funções, como propriedades de mensagem.

*No caso do produto MQ for HP NonStop, algumas operações podem diferir das descritas nesta série.

Uso do comando mqpgf e mqpcf

Primeiro, apresentarei como exibir as opções que podem ser especificadas em mqpgf e mqpcf.

1) MQPGF

Sem argumentos, o mqpgf exibirá as opções que podem ser especificadas.

$ mqpgf
-qm: nome do gerenciador de filas (por exemplo, -qm qm1, qm2,...)
-q : nome da fila
-m : mensagem de entrada
-mx : mensagem de entrada (notação hexadecimal, por exemplo, 09af..)
-f: nome do arquivo de entrada
-o : nome do arquivo de saída
-oq : nome da fila de saída (para fila para fila)('*': ReplyToQ, '**': + ReplyToQMgr)
-iq: nome da fila de entrada (para enviar e receber)
-d : nome do diretório de entrada
-g : nome do diretório de saída
-r : obter repetidamente
-b : força de recuo
-l : comprimento da mensagem para escrever
-n : contagem de mensagens para escrita ou leitura
-i : intervalo (ms) para escrita ou leitura
-sz: tamanho máximo da mensagem para leitura (byte) (padrão 12KByte)
-ds : tamanho máximo de exibição da mensagem (byte) (padrão 128Byte) (todos: mensagem inteira)
-br : Procurar mensagem
-brv : procurar mensagem (verbose)
-dp : mensagem de despejo
-dpv : mensagem de despejo (verbose)
-RAW: Saída do modo bruto
-hexadecimal : despejo hexadecimal
-s : pare antes da chamada MQI (por exemplo, -s MQCMIT)
-p : nome do processo
-nl : lista de nomes
-pcf : nome do arquivo de formato pcf
-ss : mudar para parâmetros para secundário
-sp : mudar para parâmetros para primário
-mc : obter a mensagem com o mesmo CorrelId que MsgId enviado
-im : Herdar MQMD
-AS: Tamanho da segmentação
-dl : delimitador para mensagens lógicas
-nt : número de threads
-ni : número de threads que chamam MQCONN/MQDISC internamente
-tr : Ativar rastreamento de API
-sf: o arquivo para iniciar a sincronização
-c : contagem de loop de conexão
-sd : pular MQDISC
-WP: Tempo de espera para o próximo processamento
-ca : continuar o processamento após a falha do MQCONN(X)
-AC: applend o contador para mensagem automaticamente
-cr : O número de tentativas de conexão
-y : Invocar a função de rendimento após cada chamada MQI

Opções específicas da plataforma:
-gt : Usando UOW Global para NSK
-gti : Usando UOW Global para NSK (TMFAPI: por PUT/GET)

Funções MQI :
-set : MQSET (por exemplo, MQIA_INHIBIT_GET:MQQA_GET_ALLOWED,..:..)
-inq : MQINQ (por exemplo, MQCA_ALTERATION_DATE.MQIA_CLWL_Q_PRIORITY,..)
-smp: MQSETMP (por exemplo, MQTYPE_STRING:nome da propriedade:valor,..:..)

Campos MQCD (use MQCONNX) :
-x : ConnectionName (por exemplo, -x "localhost(1414)")
-ch : ChannelName -la : LocalAddress
-cl : CertificateLabel -cs : SSLCipherSpec
-er : SSLPeerName

Campos MQMD :
-ex : Expiração (par 100ms) -ec : Codificação
-cc : CodedCharSetId -pr : Prioridade
-mi : MsgId -ci : CorrelId
-rq : ReplyToQ -rm : ReplyToQMgr
-ui : UserIdentifier -at : AccountingToken
-ap : ApplIdentityData -pn : PutApplName
-pd : PutDate -pt : PutTime
-ao : ApplOriginData
Campos MQMD Versão 2 :
-gi : GroupId -ms : MsgSeqNumber
-of : Offset -ol : OriginalLength

Campos MQRFH2:
-re : Codificação( ou MQENC_*)
-rc : CodedCharSetId( ou MQCCSI_*)
-rf : Formato (por exemplo, -rf MQFMT_STRING)
-fg : Sinalizadores -nc : NameValueCCSID( ou MQCCSI_*)
-nd : NameValueData(por exemplo, -nd "data1,data2,data3")

Campos MQCSP:
-: CSPUserId -cp : CSPPassword

Campos MQOD:
-om : ObjectQMgrName -au : AlternateUserId
-ou : ObjectRec(MQOR)(por exemplo, ObjectName:ObjectQMgrName,..:..,...)
-dq: DynamicQName (para fila de recebimento, por exemplo, "DQ*", "*" ou nome completo de 33bytes)

Campos MQPMO:
-mr : PutMsgRec(MQPMR)(por exemplo, :::MQFB_xx:,..)

Campos MQGMO:
-wi : WaitInterval(ms) -mt : MsgToken

Campos MQIMPO:
-pe : RequestedEncoding( ou MQENC_*)
-pc : RequestedCCSID( or MQCCSI_*)

MQCB fields :
-op : Operation (e.g. -op MQOP_REGISTER -op MQOP_SUSPEND ...)

MQCBD fields:
-cf : CallbackFunction (e.g. EventHandler)

Constants:
 MQMD      : MQMD_*, MQRO_*, MQMT_*, MQEI_*, MQFB_*, MQENC_*, MQCCSI_*, MQFMT_*, MQPRI_*,
             MQPER_*, MQMI_*, MQCI_*, MQACT_*, MQACTT_*, MQAT_*
 MQMDV2    : MQGI_*, MQMF_*, MQOL_*
 MQRFH2    : MQRFH_*
 MQCONNX   : MQCNO_*, MQCSP_*, MQCD_*
 MQOPEN    : MQOO_*, MQOT_*, MQOD_*
 MQPUT     : MQPMO_*, MQPMRF_*
 MQGET     : MQGMO_*, MQWI_*, MQMO_*
 MQCLOSE   : MQCO_*
 MQSETMP   : MQPD_*
 MQINQMP   : MQIMPO_*
 MQCRTMH   : MQCMHO_*
 MQCB      : MQCBT_*
*Se você especificar "-v", as informações de versão serão exibidas.
$ mqpgf -v
・・・・
[ Informações sobre a licença ]
Expira em 31.10.2021

Versão 1.4.2.8 10/03/2021
Biblioteca Versão 1.0.0.1 10/03/2021
*Se "todos" for especificado mais adiante, uma lista de constantes MQ especificáveis será exibida.
$ mqpgf -v todos
....
MQMD_VERSION_1
MQMD_VERSION_2
MQMD_CURRENT_VERSION

MQRO_EXCEPTION
....

2) MQPCF

Sem argumentos, o mqpcf exibirá as opções que podem ser especificadas.

*Se "-v" for especificado, as informações de versão também serão exibidas.
$ mqpcf -v
USO:
 mqpcf qmgr -qm qmgr
 mqpcf qms -qm qmgr
 mqpcf que -qm Qmgr
 mqpcf cque -qm qmgr
 mqpcf ques -qm Qmgr
 mqpcf queh -qm Qmgr
 mqpcf chl -qm qmgr
 chs mqpcf -qm qmgr
 mqpcf lsnr -qm qmgr
 mqpcf lsst -qm qmgr
 mqpcf cqmgr -qm qmgr
 mqpcf con -qm Qmgr
 mqpcf pngm -qm qmgr
 mqpcf ping -qm Qmgr -c Canal
 mqpcf {put | get} {enable | disable} -qm Qmgr -q Fila
 mqpcf clr -qm Qmgr -q Fila
 mqpcf rst -qm Qmgr -c Canal
 mqpcf rslv -qm Qmgr -c Canal {commit | backout}
 mqpcf sta -qm Qmgr -c Canal
 mqpcf stp -qm qmgr -c Canal
 mqpcf stalsn -qm Qmgr -ln Ouvinte
 mqpcf stplsn -qm Qmgr -ln Ouvinte
 mqpcf mqsc -qm Qmgr {-f MqscFile | -s 'Mqcmd'}
-rc : contagem de repetições
-i : intervalo de repetição (seg)
-t : tempo de exibição
-wi : O tempo máximo (seg) que o MQAI aguarda para cada mensagem de resposta
-: UserId
-ci : Senha
Selecione os parâmetros a serem exibidos (por exemplo, MQPCF CHS.. SUBESTADO MCASTAT)

[ Informações sobre a licença ]
Expira em 30/11/2021

Versão 1.4.0.11 2021.09.10
Biblioteca Versão 1.0.0.1 10/03/2021
Além disso, se você especificar apenas um comando a ser executado, as opções disponíveis para esse comando serão exibidas.
$ mqpcf colocar
USO: mqpcf {put | get} {enable | disable} -qm Qmgr -q Fila

Visão geral do descritor de mensagem (MQMD)

As mensagens MQ sempre têm uma estrutura chamada descritor de mensagem (MQMD: MQ Messege Descriptor). Várias funções MQ podem ser usadas definindo e referenciando cada campo desta estrutura. Em muitos casos, como a mensagem e a ligação do sistema foram projetadas sem entender isso bem, os benefícios dessas funções não podem ser obtidos, e as mesmas funções fornecidas pelo MQ foram implementadas no lado do aplicativo ou do sistema. Antes de começar a projetar o sistema de integração MQ e decidir sobre o formato da mensagem, certifique-se de entender suas capacidades.

Fig. 1.3

Abaixo está uma lista de campos no MQMD. As versões 1 e 2 existem no MQMD. A versão 2 adiciona alguns campos/recursos.

campo Descrição
StrucId ID da estrutura
Versão Número da versão da estrutura
Relatório Opções de mensagem de relatório
MsgType Tipo de mensagem
Caducidade Tempo de expiração da mensagem
Realimentação Feedback ou código de motivo
Codificação Codificação numérica de dados de mensagens
CodedCharSetId Identificador do conjunto de caracteres codificados dos dados da mensagem
Formato Formatar nome dos dados da mensagem
Prioridade Prioridade da mensagem
Persistência Persistência de mensagens
MsgId ID da mensagem
CorrelId ID de correlação
Contagem de BackoutCount Contador de recuo
ResponderToQ Nome da fila de resposta
ReplyToQMgr Nome do gerenciador de filas de resposta
UserIdentifier Identificação de usuário
AccountingToken Token contábil
ApplIdentityData Dados do aplicativo associados ao identificador
PutApplType Tipo de aplicativo que escreveu a mensagem
PutApplName Nome do aplicativo que escreveu a mensagem
PutDate Data em que você escreveu a mensagem
PutTime Hora em que você escreveu a mensagem
ApplOriginData Dados de aplicação relacionados à origem
   
*Abaixo estão os campos adicionados com MQMD_VERSION_2.  
ID do Grupo ID do grupo
MsgSeqNumber Número de sequência da mensagem lógica no grupo
Offset Posição relativa dos dados da mensagem física desde o início da mensagem lógica
MsgFlags Sinalizadores de mensagem
Comprimento Original Comprimento da mensagem original

mqpgf pode definir / referenciar todos os campos MQMD que são autorizados para o usuário. Se não for especificado, mqpgf define o valor padrão como MQMD. MQ define o valor inicial da estrutura MQMD com MQMD_DEFAULT. Valores específicos ?? do valor inicial da estrutura MQMD será introduzido mais tarde, mas consulte o manual do produto, se necessário.

Criando um gerenciador de filas de teste e executando testes básicos

Então, realmente coloque uma mensagem na fila e verifique o MQMD dessa mensagem.

Primeiro, crie um gerenciador de filas e uma fila para teste e inicie o servidor de comandos.

Fig. 1.4

Trabalhe usando o usuário de administração MQ que pertence ao grupo mqm.

Crie um gerenciador de filas SampleQM.

*No MQ para HP NonStop, os parâmetros passados para crtmqm são diferentes de outras plataformas. Consulte o manual do produto para obter detalhes.

$ crtmqm SampleQM
WebSphere MQ gerenciador de filas criado.
….

Inicie o gerenciador de filas criado.

$ strmqm SampleQM
IBM MQ gerenciador de filas 'SampleQM' iniciando.
O gerenciador de filas do IBM MQ 'SampleQM' começou a usar a V8.0.0.0.

*O comando para encerrar um gerenciador de filas é “endmqm ".

mqpcf usa um servidor de comando. Na nova versão do MQ, como o servidor de comandos é sincronizado com a inicialização e a parada do gerenciador de filas por padrão, iniciar o gerenciador de filas também iniciará o servidor de comandos. Se você estiver usando um nível mais antigo de MQ, como o WebSphere MQ para HP NonStop 5.3, ou se o gerenciador de filas do seu ambiente não tiver iniciado intencionalmente o servidor de comandos, será necessário iniciar o servidor de comandos manualmente.

$ strmqcsv SampleQM
IBM MQ command server started.
cf. If the queue manager's SCMDSERV property is set to "MANUAL", If you change it to "QMGR" (default), the command server will also be started at the same time QMGR starts.

   $ runmqsc SampleQM
   
   MQSC > dis qmgr scmdserv
   5 : dis qmgr scmdserv
   AMQ8408: Display Queue Manager details.
   QMNAME(SampleQM) SCMDSERV(MANUAL)
   
   MQSC > alter qmgr scmdserv(QMGR)
    6 : alter qmgr scmdserv(QMGR)
   AMQ8005: IBM MQ queue manager changed.
   MQSC > end
   $

Crie uma fila chamada SampleQ para teste.

$ runmqsc SampleQM
....
MQSC > def ql('SampleQ')
1 : def ql('SampleQ')
AMQ8006: WebSphere MQ queue created.
MQSC > end
$

*Ao usar letras minúsculas no comando MQSC, é necessário colocar a string entre aspas simples. Caso contrário, todas as letras serão convertidas em maiúsculas.

Ex. 1.1 Execução de PUT/GET e exibição de dump de mensagens

Agora use mqpgf para COLOCAR uma mensagem de teste.

$ mqpgf -qm SampleQM -q SampleQ -m "sample message"
[18/01/24 11:00:28] 1: message length: 14 put message : sample message

*Descrições das opções:

  • -qm: nome do gerenciador de filas
  • -q: Nome da fila de destino
  • -m: mensagem a ser colocada

*No caso do HP NonStop, a solicitação funciona na unidade de trabalho (MQPMO_SYNCPOINT) por padrão. A unidade de trabalho (MQPMO_NO_SYNCPOINT) é o padrão em todas as outras plataformas. Portanto, quando PUT / GET é executado no HP NonStop, o mqpgf chama a API MQCMIT() e confirma a solicitação PUT / GET. A seguinte mensagem é exibida adicionalmente.

Sucesso MQCMIT : CompCd=00 ReasonCd=00

Em seguida, GET a mensagem put no modo de navegação (MQOO_BROWSE) e despeje a mensagem. O modo de navegação não limpa as mensagens da fila depois de lê-las.

Fig. 1.5

Resultado do ensaio 1.1

$ mqpgf -qm SampleQM -q SampleQ -br
message number: 1
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[819] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205A67E3D520002805] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180124] PutTime[04085314] ApplOriginData[ ]
GroupId[0x000000000000000000000000000000000000000000000000] MsgSeqNumber[1] Offset[0] MsgFlags[0] OriginalLength[-1]
data length: 14
00000000: 7361 6D70 6C65 206D 6573 7361 6765 'sample message '

*Descrições das
opções -br: GET mensagens no modo de navegação

Quando -br é especificado, o MQMD é exibido para cada campo, e a outra parte é exibida com despejo hexadecimal e caractere visível. O MQMD exibido acima mostra o valor definido quando colocado usando MQMD_DEFAULT.

A descrição de cada campo também descreve o tipo, o tamanho, o valor inicial e se o campo é de entrada ou saída. O significado da entrada e saída aqui pode ser confuso, então vou explicar com antecedência

A seguir está a sintaxe de chamada da API MQPUT() e MQGET().

MQPUT (Hconn, Hobj, MsgDesc, PutMsgOpts, BufferLength, Buffer, CompCode, Reason)
MQGET (Hconn, Hobj, MsgDesc, GetMsgOpts, BufferLength, Buffer, DataLength, CompCode, Reason)

Tanto MQPUT() quanto MQGET() têm MsgDesc (MQMD) como um argumento, e ambos são parâmetros de entrada/saída. E I/O é decidido para cada campo do MQMD. Este significado é entrada / saída vista da API. Por exemplo, MQMD tem um campo chamado PutTime. Quando MQPUT() é chamado, esse campo é um campo de saída por padrão, e a entrada (valor especificado ao chamar a API) é ignorada, e a hora em que a mensagem foi escrita é definida por GMT (Greenwich Mean Time) após a colocação. Ele será devolvido ao aplicativo (saída). No caso de um campo de entrada fixo, o valor mostrado após chamar MQGET() ainda o valor especificado (input) antes da chamada e não indica o valor na mensagem (saídas).

para o topo

Campos MQMD

Então, eu explico os campos do MQMD um por um.

[ StrucId ]

Type: MQCHAR4
Size: 4 bytes
Initial value: MQMD_STRUC_ID_ARRAY("MD ")
Input/output: input

O ID da estrutura MQMD, fixado como “MD”.
Cada estrutura MQ tem um campo ID na parte superior que indica a estrutura.

[ Version ]

Type: MQLONG
Size: 4 bytes
Initial value: MQMD_VERSION_1(1)
Input / outpu: input

Como mencionado anteriormente, existem atualmente duas versões do MQMD: MQMD_VERSION_1 e MQMD_VERSION_2. Talvez me perguntem como ler e verificar este campo, pois a versão usada pelo sistema de destino que criou a mensagem pode ser diferente. No entanto, infelizmente esse campo é sempre um campo de entrada conforme descrito no início, portanto, não é possível verificar o valor na mensagem. O valor definido após a chamada MQGE () é o mesmo que o valor definido antes da chamada. Aqui, quando “Test Result 1.1” é confirmado, “Version [2]” é exibido. Se você usar mqpgf com PUT por padrão, use MQMD_DEFAULT e seu valor será MQMD_VERSION_1. No entanto, ao exibir dumps (quando “-br”, “-brv”, “-dp” ou “-dpv” é especificado), MQMD_VERSION_2 é usado em vez do valor padrão excepcionalmente. Assim, “Test Result 1.1” mostra apenas o valor especificado na entrada.

Ex. 1.2 GET com especificação da versão MQMD

Se você quiser chamar MQGET() com MQMD_VERSION_1 especialmente, especifique “MQMD_VERSION_1” no argumento de linha de comando, conforme mostrado abaixo.

Resultado do ensaio 1.2
$ mqpgf -qm SampleQM -q SampleQ -br MQMD_VERSION_1
message number: 1
*StrucId[MD ] Version[1] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[819] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205A67E3D520002805] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180124] PutTime[04085314] ApplOriginData[ ]

GroupId[0x000000000000000000000000000000000000000000000000] MsgSeqNumber[1] Offset[0] MsgFlags[0] OriginalLength[-1]

data length: 14
00000000: 7361 6D70 6C65 206D 6573 7361 6765 'sample message '

Descrições das opções

  • MQMD_VERSION_1: Use MQMD Ver1.

Esta é uma navegação da mesma mensagem que os resultados do teste 1.1. Ele pode ser confirmado pelo mesmo valor de MsgId (MsgId é descrito mais adiante). No entanto, o campo Versão mostra “Versão [1]”. Se você receber uma mensagem especificando MQMD_VERSION_1, se tentar ler GroupId, MsgSeqNumber, Offset, MsgFlags, OriginalLength, que são campos específicos de MQMD_VERSION_2, esses valores padrão serão retornados. Se MQMD_VERSION_1 for especificado em MQGET( ) e o campo Versão 2 for usado (não é o valor padrão), um cabeçalho MQMDE (Extended Message Descriptor) será gerado e nesse cabeçalho o valor de MQMD_VERSION_2 campos específicos será retornado. A explicação detalhada do MQMDE é omitida aqui. Se uma fila tiver uma mistura de mensagens com MQMD_VERSION_1 ou MQMD_VERSION_2, você deve sempre chamar MQGET() com MQMD_VERSION_2. Quando a mensagem com MQMD_VERSION_1 é lida com MQMD_VERSION_2 especificado, os valores padrão são definidos para o MQMD_VERSION_2 campos específicos e retornados ao aplicativo.

Versão MQMD da mensagem Valor do campo V2 da mensagem Versão MQMD especificada quando o MQGET é chamado Valor retornado no campo V2 MQMDE
MQMD_VERSION_1 - MQMD_VERSION_1 Valor padrão Nenhum
MQMD_VERSION_1 - MQMD_VERSION_2 Valor padrão Nenhum
MQMD_VERSION_2 Inadimplência MQMD_VERSION_1 Valor padrão Nenhum
MQMD_VERSION_2 Diferente do padrão MQMD_VERSION_1 Valor padrão Gerar*
MQMD_VERSION_2 Qualquer MQMD_VERSION_2 O valor da mensagem Nenhum

*O valor do campo MQMD V2 é definido.

Fig. 1.6

[ Report ]

Type: MQLONG
Size: 4 bytes
Initial value: MQRO_NONE(0)
Input / output: MQGET(): Output, MQPUT(): Input

A opção de relatório é usada para solicitar uma mensagem de relatório para verificar se a mensagem foi transferida/processada com êxito. Existem os seguintes tipos.

Tipo de relatório Origem
exceção MCA
data de validade Gerenciador de filas
Confirmar na chegada (COA) Gerenciador de filas
Confirmar na entrega (COD) Gerenciador de filas
Notificação de Ação Positiva (PAN) Aplicação do receptor
Notificação de Ação Negativa (NAN) Aplicação do receptor

Com exceção do PAN/NAN, MCA ou Queue Manager gera automaticamente mensagens de relatório. O conteúdo/resultado da mensagem de relatório é mostrado no campo “Feedback” descrito posteriormente. A “Opção de ID de Correlação” é usada para associar a mensagem de relatório à mensagem do remetente.

Por exemplo, especifique “Confirm On Arrival (COA) (MQRO_COA)” e “Confirm On Delivery (COD) (MQRO_COD_WITH_FULL_DATA)” como “tipo de relatório” e use MQRO_COPY_MSG_ID_TO_CORREL_ID (padrão) como “opção de ID de correlação”. Além disso, especifique MQMT_REQUEST (uma mensagem que requer uma resposta) como o tipo de mensagem.

MQRO_COA e MQRO_COD_WITH_FULL_DATA são definidos no MQMD. Campo Relatório com suas respectivas SO. O MQPGF fará isso automaticamente se você especificar esses dois como argumentos. Uma vez que MQRO_COPY_MSG_ID_TO_CORREL_ID é definido 0x00000000 e torna-se eficaz quando MQRO_PASS_CORREL_ID não é definido, não é necessário definir MQRO_COPY_MSG_ID_TO_CORREL_ID.

Criar uma conexão com o gerenciador de filas do lado oposto

Crie gerenciadores de filas e filas opostas, ouvintes e canais para teste. O gerenciador de filas pode ser criado na mesma máquina se não houver nenhum ambiente adicional.

Fig. 1.7

Crie o gerenciador de filas do lado oposto RemoteQM.

*No MQ para HP NonStop, os parâmetros passados para crtmqm são diferentes de outras plataformas. Consulte o manual do produto para obter detalhes.

$ crtmqm RemoteQM
WebSphere MQ queue manager created.
....

Inicie o gerenciador de filas criado.

$ strmqm RemoteQM
IBM MQ queue manager 'RemoteQM' starting.
IBM MQ queue manager 'RemoteQM' started using V8.0.0.0.

*Se o servidor de comandos não tiver sido iniciado, inicie-o da mesma forma que o SampleQM.

Crie uma fila RemoteQ para teste.

$ runmqsc RemoteQM
....
MQSC > def ql('RemoteQ')
1 : def ql('RemoteQ')
AMQ8006: IBM MQ queue created.

Crie e inicie um ouvinte em cada gerenciador de filas. Se o RemoteQM for criado em outra máquina, a porta poderá ser a mesma que o SampleQM 1414 (padrão). Se você usar o parâmetro control (qmgr) th do listner, o ouvinte também será iniciado/parado à medida que o gerenciador de filas for iniciado/parado.

*No caso do WebSphere MQ 5.3 para HP NonStop, o ouvinte é geralmente configurado como uma classe de servidor de Pathway.

« Trabalhando com SampleQM »

Criar um ouvinte

MQSC > def listener(listener) trptype(tcp) port(1414) control(qmgr)
1 : def listener(listener) trptype(tcp) port(1414) control(qmgr)
AMQ8626: IBM MQ listener created.

Inicie o ouvinte criado.

$ mqpcf stalsn -qm SampleQM -ln LISTENER
Listener Start Success. Listener Name : LISTENER

*Descrições de opções stalsn: execute o comando “Start Channel Listener” -ln: nome do ouvinte

*In case of WebSphere MQ 5.3 for HP NonStop, start the default TCP/IP listener from runmqsc.
$ runmqsc SampleQM
MQSC >sta listener
1 : sta listener
AMQ8021: WebSphere MQ Listener program started.
MQSC >end

Certifique-se de que o ouvinte foi iniciado.

$ mqpcf lsst -qm SampleQM -ln LISTENER STATUS
1: LISTENER(LISTENER) STATUS(RUNNING)

*Descrições das opções lsst: Execute o comando
“Inquire Channel Listener Status” STATUS: Exibição do campo STATUS

*mqpcf pode especificar o nome do campo a ser exibido (como “STATUS” acima) sem opções. Nesse caso, somente os parâmetros que são sempre retornados pelo comando PCF e o nome do campo especificado são exibidos.

« Trabalhando com » RemoteQM
MQSC > def listener(listener) trptype(tcp) port(1415) control(qmgr)
1 : def listener(listener) trptype(tcp) port(1415) control(qmgr)
AMQ8626: IBM MQ listener created.

A seguir, inicie o ouvinte, bem como o SampleQM e verifique se o status é “RUNNING”.

Em seguida, crie um canal de mensagem bidirecionalmente entre os dois gerenciadores de filas. Os nomes dos canais são “Sample.TO.Remote” e “Remote.TO.Sample”. Ambas as extremidades do canal devem ter o mesmo nome. Configure da seguinte maneira. O tipo de canal a ser criado é “SDR” no lado do emissor e “RCVR” no lado do receptor.

ExemploQM RemoteQM
Sample.TO.Remote(SDR) -> Sample.TO.Remote(RCVR)
Remote.TO.Sample(RCVR) <- Remote.TO.Sample(SDR)
« Trabalhando com SampleQM »

Crie uma fila (fila de transmissão) para transmissão de canal. Nesse caso, use o mesmo nome que o nome do gerenciador de filas de destino.

MQSC > def ql('RemoteQM') usage(xmitq)
4 : def ql('RemoteQM') usage(xmitq)
AMQ8006: IBM MQ queue created.

Crie um canal de remetente. Especifique o endereço IP ou o nome do host do destino e o número da porta especificado ao criar o ouvinte em conname.

MQSC > def chl('Sample.TO.Remote') chltype(sdr) conname('localhost(1415)') xmitq('RemoteQM')
8 : def chl('Sample.TO.Remote') chltype(sdr) conname('localhost(1415)') xmitq('RemoteQM')
AMQ8014: IBM MQ channel created.

Crie um canal receptor.

MQSC > def chl('Remote.TO.Sample') chltype(rcvr)
11 : def chl('Remote.TO.Sample') chltype(rcvr)
AMQ8014: IBM MQ channel created.

Crie uma definição local da fila remota, ou seja, uma definição em SampleQM que aponte para a fila RemoteQ no RemoteQM.

MQSC > def qr('RemoteQ') rqmname('RemoteQM') rname('RemoteQ')
10 : def qr('RemoteQ') rqmname('RemoteQM') rname('RemoteQ')
AMQ8006: IBM MQ queue created.

A definição local da fila remota tem um parâmetro chamado XMITQ, que não é especificado aqui. Se não for especificado, uma fila de transmissão com o mesmo nome do gerenciador de filas de destino será usada. (Desta vez, o nome da fila de transmissão é criado com o mesmo nome do gerenciador de filas de destino.)

« Trabalhando com » RemoteQM

Crie uma fila (fila de transmissão) para transmissão de canal. Faça o mesmo nome que o nome do gerenciador de filas de destino.

MQSC > def ql('SampleQM') usage(xmitq)
4 : def ql('SampleQM') usage(xmitq)
AMQ8006: IBM MQ queue created.

Crie um canal de remetente.

MQSC > def chl('Remote.TO.Sample') chltype(sdr) conname('localhost(1414)') xmitq('SampleQM')
5 : def chl('Remote.TO.Sample') chltype(sdr) conname('localhost(1414)') xmitq('SampleQM')
AMQ8014: IBM MQ channel created.

Crie um canal receptor.

MQSC > def chl('Sample.TO.Remote') chltype(rcvr)
6 : def chl('Sample.TO.Remote') chltype(rcvr)
AMQ8014: IBM MQ channel created

Uma vez criado, inicie o canal de cada remetente e verifique se os status estão “EM EXECUÇÃO”.

« Trabalhando com SampleQM »
$ mqpcf sta -qm SampleQM -c Sample.TO.Remote
Channel Start Success. Channel Name : Sample.TO.Remote

Descrições das opções sta: Execute o comando “Start Channel” -c: nome do canal

$ mqpcf chs -qm SampleQM -c Sample.TO.Remote STATUS
1: CHLINSTYPE(CURRENT) CHANNEL(Sample.TO.Remote) STATUS(RUNNING) CHLTYPE(SDR) CONNAME(127.0.0.1(1415)) RQMNAME(RemoteQM) STOPREQ(NO) SUBSTATE(MQGET) XMITQ(RemoteQM)
  • Option Descriptions
    • chs: Execute o comando “Inquire Channel Status”
« Trabalhando com » RemoteQM

Da mesma forma, inicie ‘Remote.TO.Sample’ e verifique o status.

$ mqpcf sta -qm RemoteQM -c Remote.TO.Sample
Channel Start Success. Channel Name : Remote.TO.Sample

$ mqpcf chs -qm RemoteQM -c Remote.TO.Sample STATUS
1: CHLINSTYPE(CURRENT) CHANNEL(Remote.TO.Sample) STATUS(RUNNING) CHLTYPE(SDR) CONNAME(127.0.0.1(1414)) RQMNAME(SampleQM) STOPREQ(NO) SUBSTATE(MQGET) XMITQ(SampleQM)

Verifique se a definição local da fila remota está definida corretamente e se você pode transferir a mensagem com êxito com ‘Sample.TO.Remote’. Escreva qualquer mensagem no RemoteQ, que é uma definição local de fila remota no SampleQM.

$ mqpgf -qm SampleQM -q RemoteQ -m "transfer message"
[18/01/24 18:12:28] 1: message length: 16 put message : transfer message

Confirme se a transferência foi executada com êxito pelo fato de que o número de mensagens (CURDEPTH) no RemoteQ, que é uma fila local no RemoteQM, é “1”.

$ mqpcf ques -qm RemoteQM -q RemoteQ CURDEPTH
1: QUEUE(RemoteQ) TYPE(QUEUE) CURDEPTH(1)

*Option Descriptions
ques: execute o comando
“Inquire Queue Status” CURDEPTH: Exibição do campo CURDEPTH

Depois de confirmar a chegada da mensagem, limpe a mensagem.

$ mqpcf clr -qm RemoteQM -q RemoteQ
Clear Queue Success. Queue Name : RemoteQ

*Descrições de opções clr: execute o comando “Limpar fila”

Por fim, crie uma fila para receber mensagens de relatório.

« Trabalhando com SampleQM »
$ runmqsc SampleQM
....
MQSC > def ql('ReportQ')
1 : def ql('ReportQ')
AMQ8006: IBM MQ queue created.

O lado RemoteQ não requer definição local de filas remotas para enviar mensagens de relatório. Se nenhuma definição local de fila remota existir, uma fila de transmissão com o mesmo nome do gerenciador de filas de destino será selecionada.

Ex. 1.3 Solicitando e Recebendo Mensagens de Relatório

Execute o seguinte comando. Como MQRO_COPY_MSG_ID_TO_CORREL_ID de “opção ID de correlação” é o valor 0x00000000 como mencionado acima, ele pode ser omitido.

$ mqpgf -qm SampleQM -q RemoteQ -m "mqmd.Report test" -rq ReportQ MQRO_COA MQRO_COD_WITH_FULL_DATA MQMT_REQUEST
[18/01/26 14:31:54] 1: message length: 16 put message : mqmd.Report test

*Descrições da opção -rq: Especifique MQMD. ReplyToQ
MQRO_COA: Confirmar na chegada (COA) (nenhum dos dados da mensagem do aplicativo da mensagem original está incluído na mensagem de relatório.)
MQRO_COD_WITH_FULL_DATA: Confirmar na entrega (COD) (todos os dados da mensagem do aplicativo da mensagem original estão incluídos na mensagem de relatório.)
MQMT_REQUEST: Uma mensagem que requer uma resposta

Confirme se a mensagem chegou ao gerenciador de filas de destino RemoteQ.

$ mqpcf ques -qm RemoteQM -q RemoteQ -t CURDEPTH
[18/01/26 14:32:11] 1: QUEUE(RemoteQ) TYPE(QUEUE) CURDEPTH(1)

*Descrição da opção -t: Exibir tempo de execução do comando

O remetente recebeu a mensagem de relatório Confirmar na chegada (COA) (MQRO_COA). Confirmarei o conteúdo mais tarde.

$ mqpcf ques -qm SampleQM -q ReportQ -t CURDEPTH
[18/01/26 14:32:17] 1: QUEUE(ReportQ) TYPE(QUEUE) CURDEPTH(1)

Primeiro, tente despejar a mensagem de RemoteQ do gerenciador de filas de destino.

Resultados dos ensaios 1.3.1
$ mqpgf -qm RemoteQM -q RemoteQ -brv
message number: 1
*StrucId[MD ] Version[2] Report[14592] MsgType[1] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[819] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020205A6AB4A020002902] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ReportQ ] ReplyToQMgr[SampleQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgf ] PutDate[20180126] PutTime[05315438] ApplOriginData[ ]

GroupId[0x000000000000000000000000000000000000000000000000] MsgSeqNumber[1] Offset[0] MsgFlags[0] OriginalLength[-1]

data length: 16
00000000: 6D71 6D64 2E52 6570 6F72 7420 7465 7374 'mqmd.Report test'

*Descrição da opção

-brv: GET mensagens no modo de navegação de detalhes

“14592” está definido para Relatório. Isso é 0x3900 em hexadecimal. Isso corresponde ao “OR” do parâmetro especificado abaixo.

MQRO_COA                       0x00000100
MQRO_COD_WITH_FULL_DATA        0x00003800
MQRO_COPY_MSG_ID_TO_CORREL_ID  0x00000000

Em MsgType, conforme especificado, o seguinte valor “1” correspondente a MQMT_REQUEST é definido.

MQMT_REQUEST 1

ReplyToQ é uma fila para receber relatórios e “ReportQ” é definido conforme especificado no argumento. ReplyToQMgr é um gerenciador de filas que recebe relatórios. Como não foi especificado, “SampleQM”, que é um gerenciador de filas local, é definido.

Aqui, verifique o valor definido em MsgId.

Desta vez, as mensagens RemoteQ do MQGET RemoteQM, não navegam.

$ mqpgf -qm RemoteQM -q RemoteQ
[18/01/26 14:32:30] 1: message length: 16 get message : mqmd.Report test

Verifique se o SampleQM recebeu um “Confirmar na entrega (COD) (MQRO_COD_WITH_FULL_DATA)”.

$ mqpcf ques -qm SampleQM -q ReportQ -t CURDEPTH
[18/01/26 14:32:35] 1: QUEUE(ReportQ) TYPE(QUEUE) CURDEPTH(2)

CURDEPTH tornou-se 2 casos.

Você pode confirmar que “Confirm On Arrival (COA)” é gerado ao chegar na fila oposta, e “Confirm On Delivery (COD)” é gerado quando a mensagem é processada (MQGET) da fila oposta.

Agora, verifique as duas mensagens de relatório recebidas pelo SampleQM.

Se a opção “-r” for especificada para mqpgf, todas as mensagens na fila serão recuperadas repetidamente.

Resultado do ensaio 1.3.2
$ mqpgf -qm SampleQM -q ReportQ -brv -r
message number: 1
*StrucId[MD ] Version[2] Report[0] MsgType[4] Expiry[-1] Feedback[259] Encoding[273] CodedCharSetId[819] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512052656D6F7465514D202020205A6AB4B220002306] CorrelId[0x414D512053616D706C65514D202020205A6AB4A020002902] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[RemoteQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[7] PutApplName[RemoteQM ] PutDate[20180126] PutTime[05315443] ApplOriginData[ ]

GroupId[0x000000000000000000000000000000000000000000000000] MsgSeqNumber[1] Offset[0] MsgFlags[0] OriginalLength[-1]

data length: 0
00000000: ' '

message number: 2
*StrucId[MD ] Version[2] Report[0] MsgType[4] Expiry[-1] Feedback[260] Encoding[273] CodedCharSetId[819] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512052656D6F7465514D202020205A6AB4B220002806] CorrelId[0x414D512053616D706C65514D202020205A6AB4A020002902] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[RemoteQM ] UserIdentifier[mqm ] AccountingToken[0x0534343033310000000000000000000000000000000000000000000000000006] ApplIdentityData[ ] PutApplType[7] PutApplName[RemoteQM ] PutDate[20180126] PutTime[05323011] ApplOriginData[ ]

GroupId[0x000000000000000000000000000000000000000000000000] MsgSeqNumber[1] Offset[0] MsgFlags[0] OriginalLength[-1]

data length: 16
00000000: 6D71 6D64 2E52 6570 6F72 7420 7465 7374 'mqmd.Report test'

no message available : ReportQ CompCd=02 ReasonCd=2033
  • *Descrição da opção
    • -r: GET mensagens repetidamente na fila

Ambos MsgType é definido como “4”. Isso corresponde à seguinte MQMT_REPORT e indica que é uma mensagem de relatório.

MQMT\_REPORT 4

O primeiro campo de feedback de mensagem é “259” e o segundo é “260”. Isso corresponde aos seguintes valores e indica que o primeiro caso foi COA e o segundo foi COD.

MQFB_COA 259
MQFB_COD 260

Em seguida, verifique o MsgId da mensagem enviada de “Test Result 1.3.1” e o CorrelId da mensagem de relatório.

Send Messge       MsgId   :[0x414D512053616D706C65514D202020205A6AB4A020002902]
Report Message(1) CorrelId:[0x414D512053616D706C65514D202020205A6AB4A020002902]
Report Message(2) CorrelId:[0x414D512053616D706C65514D202020205A6AB4A020002902]

O comportamento de MQRO_COPY_MSG_ID_TO_CORREL_ID padrão é copiar o MsgId da mensagem de solicitação para o CorrelId da mensagem de relatório. Você pode ver que o mesmo valor é copiado exatamente como está. Embora os detalhes sejam descritos posteriormente, MQGET() pode aguardar e GET apenas mensagens com um CorrelId específico. Junto com isso, esse mecanismo é uma função MQ que é frequentemente usada para vincular mensagens de saída e mensagens de resposta.

Finalmente, sobre os dados do aplicativo, a primeira mensagem que não solicitou os dados originais com MQRO_COA é “comprimento dos dados: 0”, e a segunda mensagem que solicitou a inclusão de todos os dados originais nos dados do relatório com MQRO_COD_WITH_FULL_DATA têm ‘mqmd. Teste de relatório’ como está. Com “_WITH_DATA”, apenas 100 bytes, com “_WITH_FULL_DATA” produzirão uma mensagem de relatório com todos os dados do aplicativo.

Fig. 1.7

[ MsgType ]

Type: MQLONG
Size: 4 bytes
Initial value: MQMT_DATAGRAM(8)
I/O: MQGET(): Output, MQPUT(): Input

Existem os seguintes tipos.

MQMT_DATAGRAM8Não requer uma mensagem de resposta
MQMT_REQUEST1Mensagem que precisa de uma resposta
MQMT_REPLY2Mensagem de resposta à solicitação
MQMT_REPORT4Mensagem de denúncia

Os resultados do ensaio 1.1, 1.2” são utilizados com MQMT_DATAGRAM(8), “Test result 1.3.1” é utilizado com MQMT_REQUEST(1) e “Test result 1.3.2” é utilizado MQMT_REPORT(4). Assim, esses são tipos de mensagens diferentes uns dos outros.

Mesmo na mensagem MQ do sistema realmente operado, às vezes esses valores não são especificados corretamente. Para evitar confusão, quando MQPUT(), especifique MsgType que representa com precisão a mensagem.

para o topo


Artigo Original