2

我们已经购买了很多许可证,进行了很多测试并获得了很多有希望的结果,并且即将发布我们的第一个版本 :)。

但是现在我们在路上遇到了一个大颠簸,这意味着如果我们不能解释和修复它,我们可能不得不放弃公共汽车:/。

我们的 Distributor 突然有如下控制错误消息:

<?xml version="1.0"?>
<ArrayOfHeaderInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <HeaderInfo>
        <Key>NServiceBus.ControlMessage</Key>
        <Value>True</Value>
    </HeaderInfo>
    <HeaderInfo>
        <Key>NServiceBus.Distributor.WorkerCapacityAvailable</Key>
        <Value>20</Value>
    </HeaderInfo>
    <HeaderInfo>
        <Key>NServiceBus.Distributor.WorkerStarting</Key>
        <Value>True</Value>
    </HeaderInfo>
    <HeaderInfo>
        <Key>CorrId</Key>
        <Value>58dd98f5-9ac0-44fb-8604-3a0f06787a35\295075</Value>
    </HeaderInfo>
    <HeaderInfo>
        <Key>NServiceBus.ExceptionInfo.Reason</Key>
        <Value>ProcessingFailed</Value>
    </HeaderInfo>
    <HeaderInfo>
        <Key>NServiceBus.ExceptionInfo.ExceptionType</Key>
        <Value>System.InvalidOperationException</Value>
    </HeaderInfo>
    <HeaderInfo>
        <Key>NServiceBus.ExceptionInfo.HelpLink</Key>
    </HeaderInfo>
    <HeaderInfo>
        <Key>NServiceBus.ExceptionInfo.Message</Key>
        <Value>Property ResponseQueue was not retrieved when receiving the message. Ensure that the PropertyFilter is set correctly.</Value>
    </HeaderInfo>
    <HeaderInfo>
        <Key>NServiceBus.ExceptionInfo.Source</Key>
        <Value>NServiceBus.Core</Value>
    </HeaderInfo>
    <HeaderInfo>
        <Key>NServiceBus.ExceptionInfo.StackTrace</Key>
        <Value>   at NServiceBus.Unicast.Transport.Transactional.TransactionalTransport.ProcessMessage(TransportMessage m) in c:\BuildAgent\work\nsb.master_6\src\impl\unicast\transport\NServiceBus.Unicast.Transport.Transactional\TransactionalTransport.cs:line 312
   at NServiceBus.Unicast.Transport.Transactional.TransactionalTransport.ReceiveMessage() in c:\BuildAgent\work\nsb.master_6\src\impl\unicast\transport\NServiceBus.Unicast.Transport.Transactional\TransactionalTransport.cs:line 275
   at NServiceBus.Utils.TransactionWrapper.RunInTransaction(Action callback, IsolationLevel isolationLevel, TimeSpan transactionTimeout) in c:\BuildAgent\work\nsb.master_6\src\utils\TransactionWrapper.cs:line 32
   at NServiceBus.Unicast.Transport.Transactional.TransactionalTransport.Process() in c:\BuildAgent\work\nsb.master_6\src\impl\unicast\transport\NServiceBus.Unicast.Transport.Transactional\TransactionalTransport.cs:line 220</Value>
    </HeaderInfo>
    <HeaderInfo>
        <Key>NServiceBus.OriginalId</Key>
        <Value>58dd98f5-9ac0-44fb-8604-3a0f06787a35\295075</Value>
    </HeaderInfo>
    <HeaderInfo>
        <Key>NServiceBus.FailedQ</Key>
        <Value>someservice.processId.distributor.control@testservices01</Value>
    </HeaderInfo>
    <HeaderInfo>
        <Key>NServiceBus.TimeOfFailure</Key>
        <Value>2013-04-30 10:07:40:750707 Z</Value>
    </HeaderInfo>
</ArrayOfHeaderInfo>

Google 告诉我们,这可能与一些线程问题有关,甚至可能与使用 peek/receive 实现 NSB 的方式有关。

上述异常与 GitHub 上的此文件有关:https ://github.com/NServiceBus/NServiceBus/blob/master/src/impl/unicast/transport/NServiceBus.Unicast.Transport.Transactional/TransactionalTransport.cs

有关我们实施的详细信息:

由于一些遗留问题,我们使用自定义 IManageUnitsOfWork,这意味着还没有针对数据库的 DTC。我不认为这可能是原因,但我认为值得一提。这是实现:

public class ManagedUnitOfWorkWithDtcSuppression : IManageUnitsOfWork
{
    private readonly IContainer _container;
    private IUnitOfWork _unitOfWork;
    private readonly TransactionScope _scope;

    public ManagedUnitOfWorkWithDtcSuppression()
    {
        _scope = new TransactionScope(TransactionScopeOption.Suppress);
        _container = ObjectFactory.GetInstance<IContainer>();
    }

    public void Begin()
    {
        _unitOfWork = _container.GetInstance<IUnitOfWork>();
    }

    public void End(Exception exception = null)
    {
        if (exception == null)
        {
            _unitOfWork.Commit();
        }

        _unitOfWork.Dispose();
        _scope.Complete();
        _scope.Dispose();
    }
}

此外,我们有一个特殊的设置,我们在 1 个运行的服务中运行 4 个相同的 AppDomain,这意味着当我们作为分发服务器启动服务时,实际上有 4 个分发服务器在运行。但这些都是公关。定义完全相互隔离。每个 AppDomain 的 IBus 都是唯一的,这已经过测试。

我们的 Distributor 配置如下所示:

        return NServiceBus.Configure.With()
            .DefineEndpointName(queuePrefix)
            .Log4Net(ObjectFactory.GetInstance<IServiceBusLog>().Build())
            .StructureMapBuilder()
            .JsonSerializer()
            .AsMasterNode()
            .RunDistributorWithNoWorkerOnItsEndpoint()
            .MsmqTransport()
            .IsTransactional(true)
            .DisableTimeoutManager()
            .DisableSecondLevelRetries()
            .UnicastBus()
            .CreateBus()
            .Start(() => NServiceBus.Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());

问题:

这里发生了什么?

我们是否因为使用 DTC 抑制而与 NSB 搞砸了,是否存在 MSMQ 错误或是否存在 NSB 错误?

4

1 回答 1

0

让我迟到一年回答!:) 我很确定您看到的是https://github.com/Particular/NServiceBus/pull/2250。基本上,微软在 .NET 3.5 和 .NET 4 之间对 MessageQueue 的实现进行了更改,使 NSB 代码非线程安全。这已在https://github.com/Particular/NServiceBus/releases/tag/3.3.10中修复

于 2014-11-20T11:11:30.190 回答