BizTalk开发系列(二十八) MSMQ 适配器

时间:2021-12-09 20:56:32

MSMQ(MicroSoft Message Queue,微软消息队列)是在多个不同的应用之间实现相互通信的一种异步传输模式,相互通信的应用可以分布于同一台机器上,也可以分布于相连的网络空间 中的任一位置。BizTalk Server 使用MSMQ Adapter向MSMQ发送以及从其接收消息。MSMQ 适配器支持 Message Queuing 2.0 和 Message Queuing 3.0。本文简要的介绍MSMQ的相关概念,演示如何使用MSMQ适配器向发送和接收其消息。最后阐述在使用MSMQ Adapter适配器的相关问题及相关解决办法。

1. MSMQ相关概念

Message 是在两台计算机间传送的数据单位。消息可以非常简单,例如只包含文本字符串;也可以更复杂,可能包含嵌入对象。

消息被发送到队列中。“消息队列”是在消息的传输过程中保存消息的容器。消息队列管理器在将消息从它的源中继到它的目标时充当中间人。队列的主要目的是提供路由并保证消息的传递;如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它。

队列类型

有两种主要类别的队列:由您或网络中的其他用户创建的队列和系统队列。用户创建的队列可能是以下任何一种队列:

  • “公共队列”在整个“消息队列”网络中复制,并且有可能由网络连接的所有站点访问。

  • “专用队列”不在整个网络中发布。相反,它们仅在所驻留的本地计算机上可用。专用队列只能由知道队列的完整路径名或标签的应用程序访问。

  • “管理队列”包含确认在给定“消息队列”网络中发送的消息回执的消息。指定希望 MessageQueue 组件使用的管理队列(如果有的话)。

  • “响应队列”包含目标应用程序接收到消息时返回给发送应用程序的响应消息。指定希望 MessageQueue 组件使用的响应队列(如果有的话)。

系统生成的队列一般分为以下几类:

  • “日记队列”可选地存储发送消息的副本和从队列中移除的消息副本。每个“消息队列”客户端上的单个日记队列存储从该计算机发送的消息副本。在服务器上为每个队列创建了一个单独的日记队列。此日记跟踪从该队列中移除的消息。

  • “死信队列”存储无法传递或已过期的消息的副本。如果过期消息或无法传递的消息是事务性消息,则被存储在一种特殊的名为“事务性死信队列”的死信队列中。死信存储在过期消息所在的计算机上。有关超时期限和过期消息的更多信息,

  • “报告队列”包含指示消息到达目标所经过的路由的消息,还可以包含测试消息。每台计算机上只能有一个报告队列。

  • “专用系统队列”是一系列存储系统执行消息处理操作所需的管理和通知消息的专用队列。

在应用程序中进行的大多数工作都涉及访问公共队列及其消息。但是,根据应用程序的日记记录、确认和其他特殊处理需要,在日常操作中很可能要使用几种不同的系统队列。

同步和异步通信

‎队列通信在本 质上是“异步”的,因为将消息发送到队列和从队列中接收消息是在不同的进程中完成的。另外,还可以异步执行接收操作。希望接收消息的用户可以针对任何给定 的队列调用 BeginReceive 方法,然后立即执行其他任务,而无需等待回复。这与人们所了解的“同步通信”截然不同。

在同步通信中,请求的发送方在执行其他任务前,必须等待来自预定接收方的响应。发送方等待的时间完全取决于接收方处理请求和发送响应所用的时间。

2. 安装和创建消息队列

  消息队列服务属于Windows组件,安装时可以在添加/删除程序的 添加/删除Windows组件里找到消息队列组件(有些功能是需要在域环境下才可以安装和使用)。如下图:

BizTalk开发系列(二十八) MSMQ 适配器

安装完MSMQ之后在计算机管理中的服务与应用程序里找到消息队列服务。如果计算机在WorkGroup模式下只能创建私有队列。

BizTalk开发系列(二十八) MSMQ 适配器

3. 演示:MSMQ Adapter

  本演示模拟从文件到消息队列和消息队列到文件的两种场景。分别应用到了MSMQ的接收和发送适配器。本演示没有使用到Orchestration,通过Public/Subscribe机制将发送和接收端口串联起来。演示步骤可以参考《BizTalk开发系列(一) "Hello World"

创建专用队列

创建消息队列非常简单,在专用队列中右击选择New.在打开的窗口中输入队列的名称。如果需要支持事务的话则选择事务。默认情况下MSMQ的存储位置 为:C:\WINDOWS\system32\msmq\storage。可以通过更改消息队列的属性进行更改。

 BizTalk开发系列(二十八) MSMQ 适配器

  创建完毕之后可以在专用队列中打到相应的队列。

  BizTalk开发系列(二十八) MSMQ 适配器

  

MSMQ发送适配器

  MSMQ发 送适配器的属性比较多,功能很强大。但配置也不是很复杂。比如一般情况下只需要设置目标队列属性即可。但如果你在创建消息队列时选择了事务那么也需要在发 送适配器中选择事务。下图是本演示的配置。设置目标队列时只需要输入: “CBCYE\PRIVATE$\DEMO”。图中显示的格式为转换后的格式。

BizTalk开发系列(二十八) MSMQ 适配器

MSDN中关于MSMQ发送适配器属性说明

属性

操作

数据类型

默认值

密码

指定远程队列的密码。与“用户名”一起使用。

字符串

用户名

指定远程队列的用户名。与“密码”一起使用。不能使用远程计算机的本地用户作为该用户名。

字符串

确认类型

指定消息队列返回给发送方应用程序的确认消息的类型。您可以选择多个确认类型。System.Messaging.AcknowledgeTypes 枚举中的所有确认类型都可用。

字符串

管理队列

指定接收确认消息的队列的名称。

字符串

正文类型

指定 MSMQ 中的消息正文类型。有效值为 .NET VarEnum 枚举的成员。

Int

8209

证书指纹

指定用于消息验证的证书的指纹。此属性与“使用验证”属性结合使用,对消息进行验证。使用“用户名”和“密码”属性可以访问队列。

字符串

目标队列

指定目标队列。
(注意:发送端口或接收位置的 URI 不能超过 256 个字符。 )

字符串

加密算法

对于加密算法,请选择“RC2”、“RC4”或“无”。

Enum

最大消息大小(KB)

指定发送给所指定队列的消息的最大大小。

UnsignedInt

1024

消息优先级

设置消息优先级。

Enum

正常

可恢复

指定是否确保消息的可恢复性。

Boolean

False

支持分段

如果将此布尔属性的值设置为 True,则会对大于 4 MB 的消息分段。

Boolean

False

超时

指定等待消息到达目标队列的最长时间。只有当使用事务时才适用。

Int

0

超时单位

设置用于“超时”属性的单位。
选择“天”、“小时”、“分钟”或“秒”。

Enum

事务性

如果将此值设置为 True,则会在您使用事务时发送消息。

Boolean

False

使用验证

如果将此布尔属性的值设置为 True,则会控制验证。此属性与“证书指纹”属性结合使用,对消息进行验证。使用“用户名”和“密码”属性可以访问队列。

Boolean

False

使用死信队列

如果将此值设置为 True,则会在出错时向死信队列发送消息。

Boolean

True

使用日志队列

如果将此值设置为 True,则会在处理消息时保存消息的副本。

Boolean

False

测试

 将测试数据放到文件夹。BizTalk会将它路由到MSMQ Adapter并将它发送到MSMQ中。你可以在计算机管理中的消息队列窗口中看到消息.则表明发送成功。

  BizTalk开发系列(二十八) MSMQ 适配器

MSMQ接收适配器

相对来说MSMQ接收适配器的配置就简单很多,只需要配置一下消息队列路径即可。

BizTalk开发系列(二十八) MSMQ 适配器

·MSDN中关于MSMQ发送适配器属性说明

区域

操作

日期类型

默认值

密码

设置用于远程队列的密码。

字符串

用户名

确定与密码结合使用以访问远程队列的用户名。不能使用远程计算机的本地用户作为该用户名。

字符串

批大小

配置批大小。MSMQ 适配器将消息分批提交给 MessageBox 数据库。默认的批大小为 20,最小批大小为 1。

注意:如果接收
位置的“事务性”属性设置为 True;则各个消息批将在 Microsoft 分布式事务处理协调器 (MSDTC) 事务的上下文中提交给
MessageBox 数据库。为消息创建的 MSDTC 事务将始终处于打开状态,直到该批中的所有消息都已保存到 MessageBox
数据库并已放置到相应的订户队列中为止。因此,MSDTC 事务的持续时间会随着“批大小”参数的增大而增长。由于同时打开大量的 MSDTC
事务会降低总体性能,因此在启用事务支持时,“批大小”参数不应设置为太大的值。

Int

20

失败时

指定适配器响应错误的方式。将此属性设置为以下值之一:

o 停止。如果发生错误,则停止通过此接收位置接收消息。

o 已挂起(不可恢复)。挂起消息并将其标记为不可恢复。

o 已挂起(可恢复)。挂起消息并将其标记为可恢复。

重要说明

如果同时应用“按序处理”属性的“True”选项、“失败时”属性的“停止”选项以及“事务性”属性的“False”选项,则不会挂起送达失败的任何消息
或将其保留在源队列中。在此方案中,会发生消息丢失。若要防止消息丢失,在使用“按序处理”功能时,只在应用“事务性”属性的“True”选项时才应用
“失败时”属性的“停止”选项。然后,在消息送达失败时,原始消息将会保留在源 MSMQ 队列中。

如果“按序处理”属性的值设为“False”,则“失败时”属性将不起作用,并且如果消息送达失败,则消息将以“已挂起(可恢复)”的状态挂起。

String

已挂起(可恢复)

按序处理

将此属性设置为 True 或 False。这表示是否按顺序处理消息。在与已将“按序送达”选项设置为 True 的 BizTalk 消息传送或业务流程发送端口一起使用时,将该属性设置为 True 表示允许按序送达消息。

Boolean

False

队列

键入有效的队列路径。根据指定的队列路径,系统将执行相应的验证。

注意: 发送端口或接收位置的 URI 不能超过 256 个字符。
注意: MSMQ 接收适配器使用轮询机制每隔 0.5 秒对为新消息指定的 MSMQ 队列进行监视。此 0.5 秒间隔为固定间隔。

字符串

事务性

将此属性设置为 True 或 False。

注意: 该适配器不支持对远程队列进行事务性读取。

Boolean

False

 测试

MSMQ接收Adapter的轮询时间为0.5秒。根据配置MSMQ接收适配器会从MSMQ从接收消息。BizTalk将消息路由到文件适配器发送端口。如下图所示可以查看到相应的文件信息:

  BizTalk开发系列(二十八) MSMQ 适配器

4. MSMQ 适配器相关问题及解决办法[陆续更新]

错误信息: The
specified destination queue "FORMATNAME:DIRECT=OS:CBCYE\PRIVATE$\DEMO"
is transactional, and the message is being sent is non-transaction.

解决办法:

在发送适配器属性中将发送端口的事务类型改为True.

错误信息:BizTalk
message 6eeed3d2-bd04-48c3-a544-22692eb13121 with size 7089.970703125
KB cannot be sent because the configured message size is 1024 KB.

原因:消息队列适配器默认消息大小为1M,但发送的数据为7M.另外Windows消息队列默认最大消息为4M.

解决办法:更改适配器的最大消息大于当前的文件大小,并启用消息队列适配器的消息分段功能。下图为启用分段功能之后7M消息被拆分的情况。 在MSMQ接收适配器会将此消息合并为一个消息。发布到Messagebox.

  BizTalk开发系列(二十八) MSMQ 适配器

错误信息:

The user does not have permissions to send messages.

或者

The adapter "MSMQ" raised an error message. Details "The user does not have permissions to receive messages.
Please check the queue permissions. ".

原因:BizTalk的当前用户对消息队列没有写入或读取的权限

解决办法:在消息队列属性的安全选项中选择相应用户的权限

 BizTalk开发系列(二十八) MSMQ 适配器

 

参考资料:

消息处理 -- MSDN

配置MSMQ 接收/发送适配器  -- MSDN