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组件里找到消息队列组件(有些功能是需要在域环境下才可以安装和使用)。如下图:

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

3. 演示:MSMQ Adapter

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

创建专用队列

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

 

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

  

  

MSMQ发送适配器

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

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中。你可以在计算机管理中的消息队列窗口中看到消息.则表明发送成功。

  

MSMQ接收适配器

相对来说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将消息路由到文件适配器发送端口。如下图所示可以查看到相应的文件信息:

  

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.

  

错误信息:

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的当前用户对消息队列没有写入或读取的权限

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

 

 

参考资料:

消息处理 -- MSDN

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

BizTalk开发系列(二十八) MSMQ 适配器的更多相关文章

  1. BizTalk开发系列(二十二) 开发自定义Map Functoid

    尽管 BizTalk Server 提供许多Functoid以支持一系列不同的操作,但仍可能会遇到需要其他方法的情况.<BizTalk开发系列 Map扩展开发>介绍了通过使用自定义 XSL ...

  2. BizTalk开发系列(二十五) SQL Adapter

    SQL Server 是.NET开发的首选数据库.当然开发BizTalk应用程序很多也离不了SQL Server.针对SQL Server的数据操作BizTalk 提供了SQL Adapter作为与数 ...

  3. BizTalk开发系列(三十八)微软BizTalk Server定价和许可[解读]

    做BizTalk的项目一段时间了,但是对BizTalk的价格和许可还不是很了解.给客户设计解决方案时大部分产品都是直接按照企业版的功能来设计,很 少考虑到价格和许可方面的因素,以为这个不是我们的事情或 ...

  4. BizTalk开发系列(二十六) 使用Web Service

    Web Service是在构建SOA平台中广泛使用的技术.在BizTalk开发过程中使用SOAP适配器接收和发送 Web Services 请求.业务流程可以发布为 Web Services 并使用外 ...

  5. BizTalk开发系列(二十九) 宏的使用

    在BizTalk中可以使用宏集合动态的让BizTalk发送处理程序使用单独的值来替换宏.常用的使用宏的发送程序有:文件发送适配器和SMTP发送适 配器.在表达式中可以使用同时使用多个宏.例如:在文件发 ...

  6. BizTalk开发系列(二十四) BizTalk项目框架建议

    Asp.NET有MVC框架,大部份的开发都是按照MVC进行的.BizTalk是面向消息的开发,不能完全采用分层的开发模式.而微软只提供了 BizTalk项目开发的基本策略,通过分析相关的Complex ...

  7. BizTalk开发系列(二十) 类型作用域

    Orchestration中的Type概念跟.NET 里的Class一样,可以在Orchestration开过过程中将多个实例绑定到一种类型.Orchestration 视图里包括的类型有Port T ...

  8. Web 前端开发人员和设计师必读文章推荐【系列二十八】

    <Web 前端开发精华文章推荐>2014年第7期(总第28期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

  9. Java开发学习(二十八)----拦截器(Interceptor)详细解析

    一.拦截器概念 讲解拦截器的概念之前,我们先看一张图: (1)浏览器发送一个请求会先到Tomcat的web服务器 (2)Tomcat服务器接收到请求以后,会去判断请求的是静态资源还是动态资源 (3)如 ...

随机推荐

  1. HTTP协议开发应用-文件服务器

    HTTP(超文本传输协议)协议是建立在TCP传输协议之上的应用层协议.HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统. 本文将重点介绍如何基于Netty的 ...

  2. XSS 跨站脚本攻击之ShellCode的调用

    1.ShellCode,最初是溢出程序和蠕虫病毒的核心,实际上是指利用一个漏洞是所执行的代码,在XSS跨站脚本中,是指由javascript等脚本编写的XSS利用代码: 2.Exploit,在黑客眼里 ...

  3. HTTP基础06--网络安全

    HTTP 的缺点 通信使用明文可能会被窃听 HTTP 报文使用明文(指未经过加密的报文)方式发送. 通信的加密 用 SSL 建立安全通信线路之后,就可以在这条线路上进行 HTTP 通信了.与 SSL ...

  4. ccpc_南阳 C The Battle of chibi dp + 树状数组

    题意:给你一个n个数的序列,要求从中找出含m个数的严格递增子序列,求能找出多少种不同的方案 dp[i][j]表示以第i个数结尾,形成的严格递增子序列长度为j的方案数 那么最终的答案应该就是sigma( ...

  5. 解决:未能加载文件或程序集“EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”

    使用nuget管理程序包,有可能在不同时间安装不同版本的Entity Framework:在项目创建初期安装的是6.0.0.0版本,后来添加的类库,安装了6.1.1版本,所以出现这个问题. 解决办法: ...

  6. BFS(八数码) POJ 1077 || HDOJ 1043 Eight

    题目传送门1 2 题意:从无序到有序移动的方案,即最后成1 2 3 4 5 6 7 8 0 分析:八数码经典问题.POJ是一次,HDOJ是多次.因为康托展开还不会,也写不了什么,HDOJ需要从最后的状 ...

  7. jquery ajax 提交信息后等待返回的提示信息

    最简单的方法: http://bbs.csdn.net/topics/390584283?page=1 $('#click').click(function){ $('#data').html('&l ...

  8. An Unfair Game-[ACdream1035]

    Problem Description There are n people and n target, everyone should get one target, no two people g ...

  9. Storm和JStorm(阿里的流处理框架)

    本文导读: 1.What——JStorm是什么? 1.1 概述 .2优点 .3应用场景 .4JStorm架构 2.Why——为什么启动JStorm项目?(与storm的区别) .1storm的现状.缺 ...

  10. Andriod开发技巧——Fragment的懒加载

    我们在做应用开发的时候,一个Activity里面可能会以viewpager(或其他容器)与多个Fragment来组合使用,而如果每个 fragment都需要去加载数据,或从本地加载,或从网络加载,那么 ...