Мы купили много лицензий, провели много тестов с многообещающими результатами и находимся на пороге нашего первого релиза :).
Но теперь мы столкнулись с большой неровностью на дороге, а это значит, что нам, возможно, придется покинуть автобус, если мы не сможем объяснить и исправить это: /.
У нашего дистрибьютора внезапно появляются сообщения об ошибках управления, подобные приведенному ниже:
<?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 сообщает нам, что это может быть связано с некоторыми проблемами потоковой передачи и, возможно, даже с тем, как NSB реализован с использованием функции peek / receive.
Вышеупомянутое исключение относится к этому файлу на 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();
}
}
Также у нас есть специальная установка, в которой мы запускаем 4 идентичных домена приложений внутри 1 запущенной службы, что означает, что когда мы запускаем службу в качестве дистрибьютора, на самом деле работает 4 дистрибьютора. Но это пр. определения полностью изолированы друг от друга. IBus уникален для каждого домена приложения, это было протестировано.
Конфигурация нашего дистрибьютора выглядит так:
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());
Вопрос:
Что здесь происходит?
Мы плохо разбираемся в NSB, потому что мы используем подавление DTC, есть ли ошибка MSMQ или ошибка NSB?