不同平台上MQ Manager的CCSID

时间:2017-08-08 15:17:05

标签: ibm-mq

如果基于Solaris的MQ Manager正在向中间Windows MQ Manager发送消息,然后将消息发送到Linux MQ管理器,那么是否需要更改CCSID才能使它们全部相同?我不这么认为,但我被迫这么做......

我遇到一个问题,客户端通过Windows上的中间MQ Manager从Solaris上的应用程序发送消息,但Linux MQ Manager最终目标应用程序收到带有CR / LF行结束字符的消息,它不能处理。接收方端组是否应该编写转换退出程序?还是MCA?

2 个答案:

答案 0 :(得分:1)

IBM MQ不处理换行符。它不像使用ftp传输文件并使用ascii模式,其中ftp将从Unix LF行结束转换为Window CR和LF行结束。对于MQ,它只是要翻译的字符集中的另一个字符。如果发送应用程序正在发送包含CR / LF字符的数据,MQ会将它们视为数据中的任何其他字符。如果接收应用程序期望带有行尾的文件作为MQ消息发送,则需要处理行尾。

在Solaris服务器上运行的Java应用程序的MQ类默认为CCSID 819,在Solaris上运行的IBM MQ队列管理器也将默认为CCSID 819. CCSID 819被描述为ISO 8859-1 ASCII

我创建了一个名为test.txt的文件,其中包含单个单词" test"并对该文件运行unix2dos。

下面的输出显示ASCII字符为HEX值:

$cat test.txt | hexdump -C
00000000  74 65 73 74 0d 0a                                 |test..|
00000006

请注意,在上面的输出中,ASCII十六进制值0dCR0aLF,这些是常见的Windows行尾。

如果我们假设默认的CCSID 819用于Solaris MQ Classes for Java应用程序和Solaris队列管理器,那么我们可以假设上面两个十六进制值代表CR / LF结束时每一行。

您声明您的Windows队列管理器具有CCSID 437,这是美国Windows服务器的典型情况。 CCSID 437被描述为USA PC-DATA,也是ASCII。

Linux队列管理器通常默认为CCSID 1208. CCSID 1208被描述为UTF-8 with IBM PUA,并且是一个可变字节字符集,每个字符可以有1到4个字节。这可以代表超过一百万个字符,包括所有ASCII字符。所有127个ASCII字符在UTF-8中表示为与ASCII中相同的单字节HEX值。

从ASCII转到UTF-8损失较少,如果使用非ASCII字符,则从UTF-8转换为ASCII可能会丢失,因为ASCII中没有等效字符,而MQ将其转换为默认替换字符HEX值1A。我已经看过这个例如欧元符号。大多数(如果不是全部)UTF-8的前255个字符与CCSID 819相同。

鉴于上述CCSID假设,转换将如下所示:

在Solaris上运行的原始IBM MQ Classes for Java应用程序,使用CR / LF行尾字符发送数据:

$cat test.txt | hexdump -C
00000000  74 65 73 74 0d 0a                                 |test..|
00000006

带有CONVERT(YES)的Solaris队列管理器发件人通道使用CCSID 437发送到Windows队列管理器:

cat test.txt | iconv -f IBM819 -t IBM437 | hexdump -C
00000000  74 65 73 74 0d 0a                                 |test..|
00000006

正如预期的那样,输出是相同的,因为819和437都是ASCII字符集,并且数据不代表前127个ASCII字符之上的任何内容。

带有CONVERT(YES)的Solaris队列管理器发件人通道使用CCSID发送到Windows队列管理器437使用CONVERT(YES)发送到具有CCSID 1208的Linux队列管理器的发件人通道:

cat test.txt | iconv -f IBM819 -t IBM437 | iconv -f IBM437 -t UTF-8 | hexdump -C
00000000  74 65 73 74 0d 0a                                 |test..|
00000006

正如预期的那样,输出是相同的,因为819和437都是ASCII字符集,UTF-8(1208)的前127个字符是普通的ASCII字符。

摘要:如果发送应用程序正在数据中发送CR / LF,则MQ消息转换不会更改此消息,如果正在使用的CCSID是上面列出的CCSID,则它甚至不会更改实际HEX字符值。发送应用程序需要更改他们发送的内容或接收应用程序需要容纳这些字符。

关于ASCII,UNICODE,UTF-8等的一个很好的参考资料可以在文章" Unicode, UTF8 & Character Sets: The Ultimate Guide"中找到。

答案 1 :(得分:0)

我在MQ环境中发现了一个糟糕的设置,而那些说它们完全相同的人并不知道或不理解MQ(并且对配置应该没有任何意见)。

此外,将发件人通道CONVERT属性设置为YES是一个非常糟糕的主意,并且只应在极端情况下使用。有关更多信息,请参阅IBM Best Practices。应该进行的唯一时间数据转换是应用程序发出带转换的MQGET。

因为,Solaris对CR / LF没有任何线索,我会猜测出现了什么问题:

  • MQMD的消息格式字段设置了值'MQSTR'。
  • Solaris队列管理器之间的发送方通道将属性CONVERT设置为YES
  • Linux上的接收应用程序没有发出,而MQGET带有转换。

问题:

  1. Solaris应用程序是否实际将消息与CR / lF放在一起?
  2. Solaris应用程序是否将MQMD格式字段设置为“MQSTR”?
  3. 为什么消息希望通过Windows队列管理器?为什么不在Solaris队列管理器和Linux队列管理器之间建立直接连接?
  4. Solaris发送方通道的CONVERT属性有什么价值?即是或否?
  5. 最简单的解决方案是让Linux应用程序使用Convert发出MQGET,假设MQMD Format字段设置为'MQSTR'。 MQ将自动将消息数据转换为正确的平台。

    如果MQMD Formet字段未设置为“MQSTR”,则MQ将不会在平台之间转换消息数据。这意味着Solaris应用程序将CR / LF放入消息中。我觉得很难相信。如果开发人员这样做,那么他们真的不知道MQ(并且不应该编程)。