Я столкнулся с чрезвычайно загадочной проблемой. У меня есть служба Windows, которая контролирует две очереди MSMQ для ввода и отправляет сообщения в другую очередь MSMQ. Хотя операция отправки кажется мгновенной с точки зрения службы, она фактически принимает сообщение ровно через три (3) минуты (как показано в окне свойств в MSMQ MMC). Я тестировал эту проблему, и ничего другого не слушал на другой стороне, чтобы я мог видеть, как набухают сообщения. Служба отправляет сообщения:Сообщения MSMQ всегда поступают с задержкой ровно на 3 минуты на том же компьютере
var proxyFactory = new ChannelFactory<IOtherServerInterface>(new NetMsmqBinding(NetMsmqSecurityMode.None)
{
Durable = true,
TimeToLive = new TimeSpan(1, 0, 0),
ReceiveTimeout = TimeSpan.MaxValue
});
IOtherServerInterface server = this.proxyFactory.CreateChannel(new EndpointAddress("net.msmq://localhost/private/myqueue"));
var task = new MyTask() { ... };
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
server.QueueFile(task);
scope.Complete();
}
Служба работает под управлением Windows Server 2008 R2. Я также тестировал его на R1 и заметил такое же поведение. Опять же, все происходит на одной машине. Все компоненты развернуты там, поэтому я не думаю, что это может быть проблема с сетью.
EDIT # 1:
Я включил диагностики WCF и что я заметил, это очень странно. Дейтаграмма MSMQ обычно записывается в обычном режиме. Однако после того, как сообщение «сообщение было закрыто», ничего не происходит. Как будто служба ждет чего-то. Примерно через 3 минуты и точно, когда поступит сообщение MSMQ (в соответствии с MMCM MSMQ), я вижу другое сообщение трассировки о предыдущем действии. Я подозреваю, что есть какое-то вмешательство.
Позвольте мне подробнее рассказать о том, как работают службы. Существует приложение IIS, которое получает задания от клиентов и переносит их в очередь MSMQ. Оттуда беспокойный сервис (MainService) подбирает их и начинает их обрабатывать. В некоторых случаях для выполнения задачи требуется другая служба (AuxService), поэтому MainService отправляет сообщение (которое всегда задерживается) в AuxService. AuxService имеет свою собственную очередь входящих сообщений, где он получает сообщения MSMQ, и когда это будет сделано, он отправляет сообщение MSMQ в MainService. Между тем поток, отправивший сообщение в AuxService, ждет, пока он не получит сигнал или пока он не истечет. Существует специальная очередь, в которой MainService ищет сообщения от AuxServices. Когда сообщение получено, вышеупомянутый поток разбуждается и возобновляет свою деятельность.
Вот представление всей архитектуры:
- приложение IIS -> Q1 -> MainService
- MainService -> Q2 -> AuxService
- AuxService -> Q3 -> MainService
Хотя все операции отмечены OneWay, мне интересно, является ли запуск MSMQ-операции в рамках другой операции MSMQ как-то незаконным. Это похоже на эмпирические данные. Если да, есть ли возможность изменить это поведение?
EDIT # 2:
Хорошо, после того, как некоторые более копать, кажется, WCF является виновником. Я включил как клиентский код в MainService, так и код сервера в AuxService для непосредственного использования MSMQ SDK, и он работает так, как ожидалось. 3-минутный тайм-аут, который я испытывал, на самом деле был временем, после которого MainService сдался и считал, что AuxService не удалось. Поэтому кажется, что по какой-то причине WCF отказывается выполнять передачу до тех пор, пока не выйдет текущая деятельность WCF.
Это по дизайну или это ошибка? Можно ли контролировать это поведение?
Вы используете аутентификацию? Иногда эти задержки связаны с проблемами сети/инфраструктуры, связанными с аутентификацией. – Groo
Я не использую аутентификацию. Более того, «Каждый» имеет полный доступ к очереди. –
Операция отправки в локальную очередь выполняется мгновенно, так как не требуется исходящая очередь. Если вы использовали Performance Monitor для отслеживания MSMQ, я ожидаю, что вы увидите, что сообщение доставлено, когда оно отправлено. Если нет, то это может быть задержкой, ожидающей совершения транзакции. Тест Easy7 состоял бы в том, чтобы отправить в очередь без транзакций и посмотреть, происходит ли такая же задержка. –