排队通信的最佳做法

本主题提供有关 Windows Communication Foundation(WCF)中排队通信的建议做法。 以下部分从方案角度讨论建议的做法。

快速、高效的排队消息处理

如果方案需要排队消息处理所提供的分离,还需要具有高效保证的快速、高性能消息处理,请使用非事务性队列并将 ExactlyOnce 属性设置为 false

此外,可以通过将属性设置为 Durablefalse,选择不产生磁盘写入费用。

安全性对性能有影响。 有关详细信息,请参阅 性能注意事项

可靠的端到端排队消息传送

以下部分介绍需要端到端可靠消息传送的方案的建议做法。

基本可靠传输

对于端到端可靠性,请将 ExactlyOnce 属性设置为 true 确保传输。 属性 Durable 可以设置为 truefalse 取决于你的要求(默认值为 true)。 通常,该 Durable 属性设置为 true ,用于端到端可靠性。 这种妥协是一种性能成本,但使消息持久化,以便在队列管理器崩溃时消息不会丢失。

事务的使用

必须使用交易机制来确保端到端的可靠性。 ExactlyOnce 保证仅确保将消息传送到目标队列。 若要确保接收到消息,请使用事务。 如果不使用事务,在服务崩溃的情况下,将丢失虽然正在传递实际上已传送到应用程序的消息。

死信队列的使用

死信队列可确保您在消息未能传递到目标队列时收到通知。 可以使用系统提供的死信队列或自定义死信队列。 通常,使用自定义死信队列是最好的,因为它使你能够将死信消息从一个应用程序发送到单个死信队列。 否则,系统上运行的所有应用程序产生的所有死信消息都会传递到单个队列。 然后,每个应用程序都必须在该死信队列中搜索,寻找与自己相关的死信消息。 有时,使用自定义死信队列并不可行,例如使用 MSMQ 3.0 时。

不建议为端对端可靠通信关闭死信队列。

有关详细信息,请参阅 使用 Dead-Letter 队列来处理消息传输失败

病毒消息处理的使用

通过病毒消息处理,可从消息处理失败的状态下恢复。

使用病毒消息处理功能时,请确保将 ReceiveErrorHandling 属性设置为适当的值。 将其设置为 Drop 表示数据丢失。 另一方面,当服务主机检测到有害消息时,将其设置为 Fault 会导致故障。 使用 MSMQ 3.0 Fault 是避免数据丢失和移出病毒消息的最佳方式。 使用 MSMQ 4.0 时,建议使用 MoveMove 将有害消息移出队列,以便服务可以继续处理新消息。 然后,病毒消息服务可以单独处理病毒消息。

有关详细信息,请参阅 病毒消息处理

实现高吞吐量

若要在单个终结点上实现高吞吐量,请使用以下内容:

  • 事务处理批处理。 事务处理批处理可确保可以在单个事务中读取许多消息。 这会优化事务提交,从而提高整体性能。 批处理的成本是,如果失败发生在批处理中的单个消息中,则会回滚整个批处理,并且必须一次处理一个消息,直到可以安全地再次批处理。 在大多数情况下,有害消息很少见,因此批处理是提高系统性能的首选方法,尤其是在你拥有参与事务的其他资源管理器时。 有关详细信息,请参阅在事务中对消息进行批处理

  • 并发。 并发可增加吞吐量,但并发也会影响对共享资源的争用。 有关详细信息,请参阅并发

  • 限流。 要实现最佳性能,需要遏制调度程序管线中的消息数。 有关如何执行此操作的示例,请参阅遏制

使用批处理时,应注意并发和遏制转换为并发批处理。

若要实现更高的吞吐量和可用性,请使用从队列中读取的 WCF 服务集群。 这要求所有这些服务在同一终结点上公开相同的协定。 农场式方法最适合消息生成速率较高的应用程序,因为它能够使多个服务同时从同一队列读取消息。

使用场时,应注意 MSMQ 3.0 不支持远程事务处理读取。 MSMQ 4.0 支持远程事务处理读取。

有关详细信息,请参阅在事务中对消息进行批处理

以工作语义为单元排队

在某些情况下,队列中的一组消息可能相关,因此,这些消息的顺序非常重要。 在这种情况下,将一组相关消息作为一个整体处理:所有消息要么都成功处理,要么都不处理。 若要实现这样的行为,请将会话用于队列。

有关详细信息,请参阅 对会话中的排队消息进行分组

关联请求-回复消息

尽管队列通常是单向的,但在某些情况下,你可能希望将收到的回复与之前发送的请求相关联。 如果需要此类关联,建议应用自己的 SOAP 消息标头,其中包含与消息相关的信息。 通常,发送方将此标头与消息附加,接收方在处理邮件并使用答复队列中的新邮件进行回复时,附加发件人的邮件标头,其中包含相关信息,以便发送者可以使用请求消息标识答复邮件。

与非 WCF 应用程序集成

将 WCF 服务或客户端与非 WCF 服务或客户端集成时使用 MsmqIntegrationBinding 。 非 WCF 应用程序可以是使用 System.Messaging、COM+、Visual Basic 或 C++编写的 MSMQ 应用程序。

使用 MsmqIntegrationBinding时,请注意以下事项:

  • WCF 消息正文与 MSMQ 消息正文不同。 使用排队绑定发送 WCF 消息时,WCF 消息正文放置在 MSMQ 消息中。 MSMQ 基础结构会遗忘此额外信息;它只看到 MSMQ 消息。

  • MsmqIntegrationBinding 支持常用的序列化类型。 根据序列化类型,泛型消息 MsmqMessage<T>的正文类型采用不同的类型参数。 例如, ByteArray 需要 MsmqMessage\<byte[]>Stream 要求 MsmqMessage<Stream>

  • 使用 XML 序列化,可以使用>属性指定已知类型,然后使用该属性来确定如何反序列化 XML 消息。

另请参阅