在WCF应用程序中设置MSMQ以确保可靠的邮件传递

在WCF应用程序中设置MSMQ以确保可靠的邮件传递,wcf,msmq,Wcf,Msmq,因此,我的任务是设置MSMQ,这样,如果我们的邮件服务器出现故障(这似乎是经常发生的),邮件就会在队列中结束,并在返回时传递。话虽如此,我不得不说,除了在过去24小时里学到的知识外,我对这方面了解不多,但我相信我知道的足够多,可以采取正确的方法,但我想问问社区中的某个人,因为考虑到我们WCF应用程序中的一些现有设置,我的同事之间存在一些困惑 目前,我们有一些使用msmq作为端点协议的服务。端点如下所示 <endpoint address="net.msmq://localhost/priv

因此,我的任务是设置MSMQ,这样,如果我们的邮件服务器出现故障(这似乎是经常发生的),邮件就会在队列中结束,并在返回时传递。话虽如此,我不得不说,除了在过去24小时里学到的知识外,我对这方面了解不多,但我相信我知道的足够多,可以采取正确的方法,但我想问问社区中的某个人,因为考虑到我们WCF应用程序中的一些现有设置,我的同事之间存在一些困惑

目前,我们有一些使用msmq作为端点协议的服务。端点如下所示

<endpoint address="net.msmq://localhost/private/Publisher"
behaviorConfiguration="BatchBehaviour" 
binding="netMsmqBinding"
bindingConfiguration="MSMQNoSecurity"
contract="HumanArc.Compass.Shared.Publisher.Interfaces.Service.IPublisherSubscriber"
name="PublishSubscriber"/>
 msgQ.ReceiveCompleted += new ReceiveCompletedEventHandler(msgQ_ReceiveCompleted)
WCF不会以某种方式重试并再次发送消息,我的假设正确吗

我认为我们应该使用如下内容来代替上面对smtp.send()的调用。(来自)

然后在服务启动的某个地方(我还不确定在哪里),我们设置了一个事件处理程序,它将实际调用SmtpClient对象上的send()。像这样的

<endpoint address="net.msmq://localhost/private/Publisher"
behaviorConfiguration="BatchBehaviour" 
binding="netMsmqBinding"
bindingConfiguration="MSMQNoSecurity"
contract="HumanArc.Compass.Shared.Publisher.Interfaces.Service.IPublisherSubscriber"
name="PublishSubscriber"/>
 msgQ.ReceiveCompleted += new ReceiveCompletedEventHandler(msgQ_ReceiveCompleted)
总而言之,我的第一个问题是哪种方式更好?创建一个使用net:msmq作为协议的服务,还是更改email方法将消息放入队列并为其设置处理程序?下一个问题,如果我关于更改调用SmtpClient.Send()的方法的假设是正确的,那么我应该在程序中的何处连接ReceiveCompleted?Out WCF服务托管在windows服务中,这意味着实际上需要调用ServiceBase.Run(servicesToRun)。有什么地方可以让我把它接上去吗?我使用WCF的经验是使用更简单的IIS托管服务,因此我不能100%确定


谢谢-我意识到这是一个很长的问题,但我一直在努力研究它,有很多信息,我似乎无法找到一个明确的解释,说明以这种方式做事情的好处与另一种方式做事情的好处

使用msmq解决下游依赖项(在本例中为smtp服务器)中的可用性的方法是有效的。然而,关于msmq,您首先应该了解一些事情

如果在msmq中创建队列,则默认情况下它是非事务性的。在此模式下,队列将不会提供您所需的保证传递语义。因此,将您的队列创建为事务性队列

然后,您可以告诉WCF,当您的服务操作收到要处理的消息时,它将登记在事务中。您可以通过定义一个实现来实现这一点:

[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void SendEmail(Something mail)
{
    ....
    smtp.Send(mail);
}
TransactionScopeRequired
告诉WCF服务操作应登记在用于将消息从发送方传输到接收方的同一事务中
TransactionAutoComplete
声明一旦操作成功完成,服务方法应提交事务。因此,在回答上面的查询时,服务操作中的故障将导致事务回滚

此时发生的情况取决于您的操作



谢谢,我基本上得出了这个结论,但是有经验的人来证实我的想法是很好的。
<netMsmqBinding>
  <binding name="netMsmqBinding_IMyServiceInterface" 
           exactlyOnce="true" 
           maxRetryCycles="3" 
           retryCycleDelay="00:01:00" 
           receiveErrorHandling="Move"> <-- this defines behavior after failure
    ...
  </binding>
</netMsmqBinding>