简体   繁体   English

WCF MSMQ 4.0中的毒性消息处理

[英]Poison Message Handling in WCF MSMQ 4.0

I am trying to handle the poison messages in WCF with MSMQ transport. 我试图用MSMQ传输处理WCF中的有害消息。

I followed the below link for creating the original and poison services. 我按照以下链接创建了原始和毒药服务。

http://msdn.microsoft.com/en-us/library/aa395218.aspx http://msdn.microsoft.com/en-us/library/aa395218.aspx

The only difference is instead of self hosting , I hosted the 2 servces in IIS with a single host project. 唯一的区别是不是自托管,而是在IIS中使用单个主机项目托管了2个服务。

The configuration of both the services is below. 两种服务的配置如下。

<services>
  <service behaviorConfiguration="MainMSMQWCFService.Service1Behavior"
    name="MainMSMQWCFService.OrderProcessorService">
    <endpoint address="net.msmq://localhost/private/servicemodelsamplespoison"
      binding="netMsmqBinding" bindingConfiguration="PoisonBinding"
      contract="MainMSMQWCFService.IOrderProcessor" />
  </service>
  <service behaviorConfiguration="MainMSMQWCFService.PoisonHandlingServiceBehavior"
    name="MainMSMQWCFService.PoisonHandlingService">
    <endpoint address="net.msmq://localhost/private/servicemodelsamplespoison;poison" 
              binding="netMsmqBinding"
              bindingConfiguration="PoisonBinding2"
              contract="MainMSMQWCFService.IOrderProcessor">
    </endpoint>
  </service>
</services>

Both services are running properly. 两种服务都正常运行。

The issue is when the message is put into the poison queue, the poison service is not processing the message. 问题是当消息被放入毒物队列时,毒物服务不处理消息。 I observed the messages in Poison queue, they are targeting to original service only. 我观察了Poison队列中的消息,它们仅针对原始服务。 then how the poison service can process them? 然后毒药服务如何处理它们? after going through MSDN , I got to know that by setting Service behavior attribute , WCF channel takes care this issue. 通过MSDN后,我知道通过设置服务行为属性,WCF通道会解决这个问题。 The following paragraoh explains the same. 以下paragraoh解释相同。

"Messages in the poison message queue are messages that are addressed to the service that is processing the message, which could be different from the poison message service endpoint. Therefore, when the poison message service reads messages from the queue, the WCF channel layer finds the mismatch in endpoints and does not dispatch the message. In this case, the message is addressed to the order processing service but is being received by the poison message service. To continue to receive the message even if the message is addressed to a different endpoint, we must add a ServiceBehavior to filter addresses where the match criterion is to match any service endpoint the message is addressed to. This is required to successfully process messages that you read from the poison message queue." “有害消息队列中的消息是发往处理消息的服务的消息,可能与有害消息服务端点不同。因此,当有害消息服务从队列中读取消息时,WCF通道层会发现端点不匹配并且不调度消息。在这种情况下,消息被发送到订单处理服务但是被有害消息服务接收。即使消息被发送到不同的端点,也要继续接收消息,我们必须添加一个ServiceBehavior来过滤匹配条件匹配消息所针对的任何服务端点的地址。这是成功处理从有害消息队列中读取的消息所必需的。

But my poison service is not processing the poisoned messages? 但是我的毒药服务没有处理中毒的消息?

I am not able to figure out the issue. 我无法弄清楚这个问题。

I have the same problem. 我也有同样的问题。

I was wondering if it is because when hosting netMsmq services in IIS, the queue name has to match the service name. 我想知道是否因为在IIS中托管netMsmq服务时,队列名称必须与服务名称匹配。 In the case of the initial message queue, this is OK (eg the queue would be something like private/SimpleService/Service1.svc), but then the poison queue is called private/SimpleService/Service1.svc;poison, which obviously does not match the poison service name. 在初始消息队列的情况下,这是正常的(例如,队列将类似于private / SimpleService / Service1.svc),但是毒性队列被称为private / SimpleService / Service1.svc; poison,这显然不是匹配毒药服务名称。

I have had samples working fine when self-hosted. 我自己托管的样本工作正常。 This problem only seems to be with IIS hosting. 这个问题似乎只与IIS托管有关。

If this is the problem, then I have no solution I'm afraid... 如果这是问题,那我恐怕没有解决方案......

Update: 更新:

This comment from 这个评论来自

http://msdn.microsoft.com/en-us/library/ms789042(v=VS.90).aspx http://msdn.microsoft.com/en-us/library/ms789042(v=VS.90).aspx

Suggests that the problem is as I thought: 建议问题是我想的:

"A WAS-hosted application cannot be activated based on messages in a system queue, such as the system-wide dead-letter queue, or sub-queues, such as poison sub-queues. This is a limitation for this version of the product" “无法基于系统队列中的消息(例如系统范围的死信队列)或子队列(例如有毒子队列)激活WAS托管的应用程序。这是此版本产品的限制“

I don't think it is possible to specify an alternative custom poison message queue, so the alternatives are: 我不认为可以指定备用自定义毒药消息队列,因此备选方案是:

1) Write code in the service implementation to move messages to an alternative queue on failure 2) Use a trigger to transfer messages from the poison message queue to another queue and have an IIS hosted service listen to that 3) Host your poison message service in a custom EXE instead of IIS 1)在服务实现中编写代码,以便在失败时将消息移动到备用队列2)使用触发器将消息从病毒消息队列传输到另一个队列,并让IIS托管服务监听3)托管您的有害消息服务自定义EXE而不是IIS

I recently ran into this with IIS7. 我最近遇到了IIS7。 Yes, by default, WAS-hosted application don't work on poison queues However, I believe there is a way to host WCF service in IIS that would detect poison messages. 是的,默认情况下,WAS托管的应用程序不适用于有毒队列但是,我相信有一种方法可以在IIS中托管可以检测有害消息的WCF服务。 The way I think about it is that poison message service is really sub-service of the main WCF service and it's sort of dependent on the main service. 我想到的方式是,有毒消息服务实际上是主要WCF服务的子服务,它依赖于主服务。 To host the sub-service in WCF, I implemented custom ServiceHostFactory. 为了在WCF中托管子服务,我实现了自定义ServiceHostFactory。 Inside ServiceHostFactory, I override OnOpening and OnClosing events of the main service host to open and close the poison message service. 在ServiceHostFactory中,我覆盖主服务主机的OnOpening和OnClosing事件,以打开和关闭有害消息服务。 Here is a sample code: 这是一个示例代码:

public class HostFactory : ServiceHostFactory
{ 
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        SomeServiceHost host = new SomeServiceHost(serviceType, baseAddresses);
        host.PoisonMsmqServiceType = typeof(PoisonHandler);
        return host;
    }
}

public class SomeServiceHost : ServiceHost
{
    private ServiceHost poisonMsmqServiceHost;


    public Type PoisonMsmqServiceType { get; set; }

     public SomeServiceHost(Type serviceType, params Uri[] baseAddresses)
    : base(serviceType, baseAddresses) { }

    protected override void OnOpening()
    {
        base.OnOpening();

        if (this.PoisonMsmqServiceType != null)
        {
            this.poisonMsmqServiceHost = new ServiceHost(this.PoisonMsmqServiceType);
            this.poisonMsmqServiceHost.Open();
        }
    }

    protected override void OnClosing()
    {
        base.OnClosing();

        if (this.poisonMsmqServiceHost != null)
        {
            this.poisonMsmqServiceHost.Close();
            this.poisonMsmqServiceHost = null;
        }
    }
}

After that, just set the 'Factory' attribute on you .svc file with your custom host factory class and it should take care of the poison message handling for you. 之后,只需使用自定义主机工厂类在.svc文件上设置'Factory'属性,它应该为您处理有害消息处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM