佇列通訊的最佳做法Best Practices for Queued Communication

本主題會提供佇列通訊中 Windows Communication Foundation (WCF) 的建議的做法。This topic provides recommended practices for queued communication in Windows Communication Foundation (WCF). 下列各節由案例的觀點來討論建議的做法。The following sections discuss recommended practices from a scenario perspective.

快速、最佳的佇列傳訊Fast, Best-Effort Queued Messaging

在需要佇列傳訊提供分離、且以最佳保證提供快速、高效能的傳訊案例中,使用非交易式佇列並且將 ExactlyOnce 屬性設定為 falseFor scenarios that require separation that queued messaging provides and fast, high-performance messaging with best-effort assurances, use a non-transactional queue and set the ExactlyOnce property to false.

此外,您可以透過將 Durable 屬性設定為 false,來選擇不要造成磁碟寫入的成本。In addition, you can choose not to incur the cost of disk writes by setting the Durable property to false.

安全性隱含對效能的影響。Security has implications on performance. 如需詳細資訊,請參閱 < 效能考量For more information, see Performance Considerations.

可靠的端對端佇列傳訊Reliable End-to-End Queued Messaging

下列各節描述需要端對端可靠傳訊的案例之建議做法。The following sections describe recommended practices for scenarios that require end-to-end reliable messaging.

基本可靠傳輸Basic Reliable Transfer

對於端對端可靠性,將 ExactlyOnce 屬性設定為 true 以確保傳輸。For end-to-end reliability, set the ExactlyOnce property to true to ensure transfer. 視您的需要將 Durable 屬性設定為 truefalse (預設為 true)。The Durable property can be set to true or false depending on your requirements (the default is true). 一般而言,Durable 屬性設定為 true 以作為端對端可靠性的一部分。Generally, the Durable property is set to true as part of end-to-end reliability. 危害是一種效能成本,但會使訊息成為永久性的訊息,因此佇列管理員中止時,不會遺失訊息。The compromise is a performance cost, but makes the message durable so that the message is not lost if a queue manager crashes.

使用異動Use of Transactions

您必須使用異動來確保端對端的可靠性。You must use transactions to ensure end-to-end reliability. ExactlyOnce 保證只能夠確保訊息傳送到目標佇列。ExactlyOnce assurances only ensure that messages are delivered to the target queue. 若要確保收到訊息,請使用交易。To ensure that the message is received, use transactions. 如果沒有使用交易,在服務中止時,您會遺失實際上正在傳遞給應用程式的訊息。Without transactions, if the service crashes, you lose the message that is being delivered but is actually delivered to the application.

使用寄不出的信件佇列Use of Dead-letter Queues

寄不出的信件佇列確保在訊息無法傳遞至目標時通知您。Dead-letter queues ensure that you are notified if a message fails to be delivered to the target queue. 灺可以使用系統提供的寄不出的信件佇列,或自訂的寄不出的信件佇列。You can use the system-provided dead-letter queue or a custom dead-letter queue. 一般而言,使用自訂的寄不出的信件佇列是最佳選擇,因為它可以讓您將寄不出的信件訊息從某個應用程式傳送到單一寄不出的信件佇列中。In general, using a custom dead-letter queue is best because it enables you to send dead-letter messages from one application into a single dead-letter queue. 否則,針對在系統上執行的所有應用程式產生的所有寄不出的信件訊息會傳遞到單一佇列。Otherwise, all dead-letter messages that occur for all applications running on the system are delivered to a single queue. 然後每個應用程式必須搜尋整個寄不出的信件佇列,以尋找和該應用程式相關的寄不出的信件訊息。Each application must then search though the dead-letter queue to find the dead-letter messages that are relevant to that application. 有時使用自訂的寄不出的信件佇列不可行,例如在使用 MSMQ 3.0 時。Sometimes, using a custom dead-letter queue is not feasible, such as when using MSMQ 3.0.

不建議關閉用於端對端可靠通訊的寄不出的信件佇列。Turning off dead-letter queues for end-to-end reliable communication is not recommended.

如需詳細資訊,請參閱 < 使用寄不出信件佇列來處理訊息傳輸失敗For more information, see Using Dead-Letter Queues to Handle Message Transfer Failures.

使用有害訊息處理Use of Poison-Message Handling

有害訊息處理提供從失敗中復原的能力以處理訊息。Poison-message handling provides the ability to recover from the failure to process messages.

使用有害訊息處理功能時,請確定 ReceiveErrorHandling 屬性已設定為適當的值。When using the poison-message handling feature, ensure that the ReceiveErrorHandling property is set to the appropriate value. 設定為 Drop 表示資料遺失。Setting it to Drop means the data is lost. 另一方面,當偵測到有害訊息時,將它設定為 Fault 會導致服務主機發生錯誤。On the other hand, setting it to Fault faults the service host when it detects a poison message. 使用 MSMQ 3.0 時,Fault 是避免資料遺失與移走有害訊息的最佳選項。Using MSMQ 3.0, Fault is the best option to avoid data loss and move the poison message out of the way. 使用 MSMQ 4.0 時,Move 是建議的處理方式。Using MSMQ 4.0, Move is the recommended approach. Move 會將有害訊息移出佇列,讓服務可以繼續處理新訊息。Move moves a poisoned message out of the queue so the service can continue to process new messages. 然後有害訊息服務可以個別處理有害訊息。The poison-message service can then process the poison message separately.

如需詳細資訊,請參閱 < 有害訊息處理For more information, see Poison Message Handling.

達到高輸送量Achieving High Throughput

若要在單一端點上達到高輸送量,可以使用下列幾項:To achieve high throughput on a single endpoint, use the following:

  • 交易的批次處理。Transacted batching. 異動的批次處理確保可以在單一異動中讀取多則訊息。Transacted batching ensures that many messages can be read in a single transaction. 這樣可以最佳化異動認可,因此增加了整體效能。This optimizes transaction commits, increasing overall performance. 批次處理的代價在於,如果批次內的一則訊息中發生失敗,整個批次都要復原,而且必須一次處理一則訊息,直到再度對批次而言是安全的為止。The cost of batching is that if a failure occurs in a single message within a batch, then the entire batch is rolled back and the messages must be processed one at a time until it is safe to batch again. 在大部分情況中,傾向於使用批次處理增加系統效能,特別是當您有參與異動的其他資源管理員時。In most cases, poison messages are rare, so batching is the preferred way to increase system performance, particularly when you have other resource managers that participate in the transaction. 如需詳細資訊,請參閱 < 異動中批次處理的訊息For more information, see Batching Messages in a Transaction.

  • 並行。Concurrency. 並行可以增加輸送量,但也會影響對共用資源的爭用。Concurrency increases throughput, but concurrency also affects contention to shared resources. 如需詳細資訊,請參閱 < 並行For more information, see Concurrency.

  • 節流。Throttling. 為了得到最佳效能,控制在發送器管線中的訊息數目。For optimal performance, throttle the number of messages in the dispatcher pipeline. 如需如何執行這項操作的範例,請參閱 < 節流For an example of how to do this, see Throttling.

使用批次處理時,注意轉換為並行批次的並行與節流。When using batching, be aware that concurrency and throttling translate to concurrent batches.

若要達到更高的輸送量和可用性,使用從佇列讀取的 WCF 服務的伺服陣列。To achieve higher throughput and availability, use a farm of WCF services that read from the queue. 這樣做需要所有這些服務在相同的端點上公開相同的合約。This requires that all of these services expose the same contract on the same endpoint. 陣列方法最適合有高訊息產生速率的應用程式,因為它對所有來自相同佇列的讀取啟用多種服務。The farm approach works best for applications that have high production rates of messages because it enables a number of services to all read from the same queue.

使用陣列時,注意 MSMQ 3.0 不支援遠端交易的讀取。When using farms, be aware that MSMQ 3.0 does not support remote transacted reads. MSMQ 4.0 不支援遠端交易的讀取。MSMQ 4.0 does support remote transacted reads.

如需詳細資訊,請參閱 < 異動中批次處理的訊息Windows Vista、 Windows Server 2003 和 Windows XP 中的佇列功能差異For more information, see Batching Messages in a Transaction and Differences in Queuing Features in Windows Vista, Windows Server 2003, and Windows XP.

有工作單元語意的佇列Queuing with Unit of Work Semantics

在有些案例中,可能與佇列中的訊息群組有關,因此這些訊息的排序非常重要。In some scenarios a group of messages in a queue may be related and, therefore, the ordering of these messages is significant. 在這類案例中,將相關訊息群組視為單一單元而加以處理:全部都成功處理或全部都未成功處理。In such scenarios, process a group of related messages together as a single unit: either all of the messages are processed successfully or none are. 若要實作這類行為,請使用有佇列的工作階段。To implement such behavior, use sessions with queues.

如需詳細資訊,請參閱 < 的工作階段中群組佇列訊息For more information, see Grouping Queued Messages in a Session.

相關的要求回覆訊息Correlating Request-Reply Messages

雖然佇列都是單向的,在有些案例中,您可能想要將收到的回覆與之前傳送的要求相互關聯。Though queues are typically one-way, in some scenarios you may want to correlate a reply received to a request sent earlier. 如果您需要這類關聯,建議您套用自己的 SOA 訊息標頭,此標題包含與訊息關聯的資訊。If you require such correlation, it is recommended that you apply your own SOAP message header that contains correlation information with the message. 一般來說,寄件者將此標頭附加在訊息中,而處理訊息並以回覆佇列上的新訊息回覆的接收者附加包含關聯資訊的傳送者訊息標頭,因此傳送者可以透過要求訊息來識別回覆訊息。Typically, the sender attaches this header with the message, and the receiver, upon processing the message and replying back with a new message on a reply queue, attaches the sender's message header that contains the correlation information so that the sender can identify the reply message with the request message.

整合非 WCF 應用程式Integrating with Non-WCF Applications

使用MsmqIntegrationBinding整合 WCF 服務或用戶端與非 WCF 服務或用戶端時。Use MsmqIntegrationBinding when integrating WCF services or clients with non-WCF services or clients. 非 WCF 應用程式可以是使用 System.Messaging、 COM +、 Visual Basic 撰寫的 MSMQ 應用程式或C++。The non-WCF application can be an MSMQ application written using System.Messaging, COM+, Visual Basic, or C++.

使用 MsmqIntegrationBinding 時,請注意下列各點:When using MsmqIntegrationBinding, be aware of the following:

  • WCF 訊息內文不是 MSMQ 訊息內文相同。A WCF message body is not the same as a MSMQ message body. 傳送 WCF 訊息時使用的佇列繫結,則會將 WCF 訊息內文放置內部 MSMQ 訊息。When sending a WCF message using a queued binding, the WCF message body is placed inside of a MSMQ message. MSMQ 基礎結構未注意到此額外資訊,它只看到 MSMQ 訊息。The MSMQ infrastructure is oblivious to this extra information; it sees only the MSMQ message.

  • MsmqIntegrationBinding 支援常見的序列化類型。MsmqIntegrationBinding supports popular serialization types. 根據序列化類型、泛型訊息的本文類型、MsmqMessage<T>,採用不同類型的參數。Based on the serialization type, the body type of the generic message, MsmqMessage<T>, takes different type parameters. 例如,ByteArray 需要 MsmqMessage\<byte[]>,而 Stream 需要 MsmqMessage<Stream>For example, ByteArray requires MsmqMessage\<byte[]> and Stream requires MsmqMessage<Stream>.

  • 使用 XML 序列化,您可以指定已知型別使用KnownTypes屬性<行為 >之後要用來決定如何將 XML 訊息還原序列化的項目。With XML serialization, you can specify the known type using the KnownTypes attribute on the <behavior> element that is then used to determine how to deserialize the XML message.

另請參閱See also