Устранение неполадок обмена сообщениями с использованием очередей

Этот раздел содержит распространенные вопросы и справку по устранению неполадок при использовании очередей в Windows Communication Foundation (WCF).

Часто задаваемые вопросы

Q: Я использовал WCF Beta 1 и установил исправление MSMQ. Требуется ли удалять исправление?

Ответ. Да. Это исправление больше не поддерживается. WCF теперь работает в MSMQ без необходимости исправления.

Q: Существует две привязки для MSMQ: NetMsmqBinding и MsmqIntegrationBinding. Какую необходимо использовать и когда?

A: Используйте , NetMsmqBinding если вы хотите использовать MSMQ в качестве транспорта для обмена данными в очереди между двумя приложениями WCF. Используйте , если вы хотите использовать существующие приложения MSMQ для взаимодействия с новыми MsmqIntegrationBinding приложениями WCF.

Q: Нужно ли обновлять MSMQ для использования NetMsmqBinding привязок и MsmqIntegration ?

Ответ. Нет. Обе привязки работают с MSMQ 3.0 в Windows XP и Windows Server 2003. Некоторые функции привязок становятся доступными при обновлении до MSMQ 4.0 в Windows Vista.

Q: Какие функции NetMsmqBinding привязок и MsmqIntegrationBinding доступны в MSMQ 4.0, но не в MSMQ 3.0?

A: В MSMQ 4.0 доступны следующие функции, но не в MSMQ 3.0:

  • Пользовательская очередь недоставленных сообщений поддерживается только в MSMQ 4.0.

  • MSMQ 3.0 и 4.0 обрабатывают опасные сообщения по-разному.

  • Удаленные чтения в транзакциях поддерживаются только MSMQ 4.0.

Q: Можно ли использовать MSMQ 3.0 с одной стороны связи в очереди и MSMQ 4.0 с другой стороны?

Ответ. Да.

Q: Я хочу интегрировать существующие приложения MSMQ с новыми клиентами или серверами WCF. Требуются ли обновления для обеих сторон инфраструктуры MSMQ?

Ответ. Нет. Для обеих сторон обновление до MSMQ 4.0 не требуется.

Устранение неполадок

Данный раздел содержит ответы на вопросы, связанные с устранением распространенных неполадок. Некоторые вопросы, являющиеся известными ограничениями, описаны также в заметках о выпуске.

Q: Я пытаюсь использовать частную очередь, и я получаю следующее исключение: System.InvalidOperationException: НЕДОПУСТИМЫй URL-адрес. URL-адрес очереди не может содержать символ "$". Используйте синтаксис net.msmq://machine/private/queueName, чтобы адресовать частную очередь.

A: Проверьте универсальный код ресурса очереди (URI) в конфигурации и коде. Не используйте символ "$" в универсальном коде ресурса (URI). Например, чтобы обратиться к частной очереди с именем OrdersQueue, укажите URI как net.msmq://localhost/private/ordersQueue.

Q: Вызов ServiceHost.Open() приложения в очереди вызывает следующее исключение: System.ArgumentException: базовый адрес не может содержать строку запроса URI. Почему?

A: Проверьте URI очереди в файле конфигурации и коде. Хотя очереди MSMQ поддерживают использование символа "?", универсальные коды ресурсов (URI) интерпретируют этот символ как начало строки запроса. Чтобы избежать этого, не используйте символ "?" в именах очередей.

Q: Отправка выполнена успешно, но на получателе не вызывается никаких операций службы. Почему?

A: Чтобы определить ответ, ознакомьтесь со следующим списком проверка:

  • Проверьте, совместимы ли требования транзакционной очереди с заданными гарантиями. Обратите внимание на следующие принципы.

    • Устойчивые сообщения (датаграммы и сеансы) с гарантиями "ровно один раз" (ExactlyOnce = true) можно отправлять только в очередь транзакций.

    • Сеансы можно отправлять только с гарантиями доставки точно по одному разу.

    • Необходимо, чтобы в сеансе транзакция получала сообщения из транзакционной очереди.

    • Вы можете отправлять или получать неустойчивые или устойчивые сообщения (только датаграммы) без гарантий (ExactlyOnce = false) только в очередь, не связанную с транзакциями.

  • Проверьте очередь недоставленных писем. Если в этой очереди есть сообщения, определите причину, по которой они не были доставлены.

  • Проверьте очереди исходящих сообщений на наличие проблем с подключением и адресацией.

Q: Я указал настраиваемую очередь недоставленных сообщений, но при запуске приложения отправителя я получаю исключение, указывающее, что очередь недоставленных сообщений не найдена или у отправляющего приложения нет разрешения на очередь недоставленных сообщений. Почему это происходит?

A: URI пользовательской очереди недоставленных сообщений должен содержать "localhost" или имя компьютера в первом сегменте, например net.msmq://localhost/private/myAppdead-letter queue.

Q: Всегда ли необходимо определять пользовательскую очередь недоставленных сообщений или есть очередь недоставленных сообщений по умолчанию?

A: Если гарантии имеют значение "ровно один раз" (ExactlyOnce = true), а пользовательская очередь недоставленных сообщений не указана, по умолчанию используется общесистемная транзакционная очередь недоставленных сообщений.

Если гарантии отсутствуют (ExactlyOnce = false), по умолчанию не используется функция очереди недоставленных сообщений.

Q: Моя служба выдает в SvcHost.Open сообщение "Требования EndpointListener не могут быть выполнены listenerFactory". Почему?

A. Проверьте контракт службы. Возможно, вы забыли поместить "IsOneWay=true" для всех операций службы. Очереди поддерживают только односторонние операции службы.

Q: В очереди есть сообщения, но операция службы не вызывается. В чем заключается проблема?

A: Определите, произошел ли сбой узла службы. Убедиться в этом можно, просмотрев трассировку или реализовав IErrorHandler. По умолчанию сбой узла службы происходит при обнаружении подозрительного сообщения.

Q: В очереди есть сообщения, но служба, размещенная в очереди на веб-сайте, не активируется. Почему?

A: Наиболее распространенной причиной являются разрешения.

  1. Убедитесь в том, что выполняется процесс NetMsmqActivator и удостоверению процесса NetMsmqActivator предоставлено разрешение на чтение и поиск для данной очереди.

  2. Если процесс NetMsmqActivator отслеживает очереди на удаленном компьютере, убедитесь в том, что NetMsmqActivator не выполняется с маркером ограниченного доступа. Чтобы выполнить процесс NetMsmqActivator с маркером неограниченного доступа, используется следующий код.

    sc sidtype NetMsmqActivator unrestricted
    

Проблемы с веб-узлом, не связанные с безопасностью, см. в статье Веб-размещение приложения в очереди.

Q: Каков самый простой способ доступа к сеансам?

A: Установите автозавершение=true для операции, которая соответствует последнему сообщению в сеансе, и задайте параметр AutoComplete=false для всех оставшихся операций службы.

Q: Почему моя служба вызывает ProtocolException при чтении из очереди, содержащей как сообщения сеанса в очереди, так и сообщения датаграмм?

A: Существует фундаментальное различие в способе создания сообщений сеанса в очереди и сообщений данных в очереди. Вследствие этого, служба, ожидающая чтения сообщения сеанса из очереди не может получить сообщение датаграммы из очереди, а служба, ожидающая чтения сообщения датаграммы из очереди не может получить сообщения сеанса. При попытке чтения сообщений обоих типов из одной очереди будет получено следующее исключение.

System.ServiceModel.MsmqPoisonMessageException: The transport channel detected a poison message. This occurred because the message exceeded the maximum number of delivery attempts or because the channel detected a fundamental problem with the message. The inner exception may contain additional information.
---> System.ServiceModel.ProtocolException: An incoming MSMQ message contained invalid or unexpected .NET Message Framing information in its body. The message cannot be received. Ensure that the sender is using a compatible service contract with a matching SessionMode.

Системная очередь недоставленных сообщений, а также любая пользовательская очередь недоставленных сообщений особенно чувствительна к этой проблеме, если приложение отправляет с одного компьютера как сообщения сеанса в очереди, так и сообщения датаграммы. Если сообщение не удается отправить, оно перемещается в очередь недоставленных сообщений. При этих обстоятельствах в очереди недоставленных сообщений могут быть как сообщения сеанса, так и сообщения датаграмм. Невозможно отделить оба типа сообщений во время выполнения при чтении из очереди, поэтому приложения не должны отправлять сообщения сеанса в очереди и сообщения датаграмм в очереди с одного компьютера.

Интеграция MSMQ: устранение конкретных неполадок

Q: Когда я отправляю сообщение или открываю узел службы, я получаю сообщение об ошибке, указывающее, что схема неправильная. Почему?

A: При использовании привязки интеграции MSMQ необходимо использовать схему msmq.formatname. Например, msmq.formatname:DIRECT=OS:.\private$\OrdersQueue. Однако если задана пользовательская очередь недоставленных сообщений, необходимо использовать схему net.msmq.

Q: При использовании имени общедоступного или закрытого формата и открытии узла службы в Windows Vista возникает ошибка. Почему?

A: Канал интеграции WCF в Windows Vista проверяет, можно ли открыть вложенную очередь для main очереди приложений для обработки подозрительных сообщений. Имя вложенной очереди является производным от URI msmq.formatname, переданного прослушивателю. Имя вложенной очереди в MSMQ может быть только именем прямого формата. Из-за этого возникает ошибка. Измените URI очереди на непосредственное имя формата.

Q: При получении сообщения от приложения MSMQ сообщение находится в очереди и не считывается принимающим приложением WCF. Почему?

A: Проверьте, есть ли в сообщении текст. Если в сообщении отсутствует тело, канал интеграции MSMQ игнорирует его. Реализуйте интерфейс IErrorHandler, чтобы получать уведомления об исключениях, и проверьте трассировки.

Q: При запуске примера, использующего привязку по умолчанию в режиме рабочей группы, сообщения отправляются, но получатель никогда не получает.

A: По умолчанию сообщения подписываются с помощью внутреннего сертификата MSMQ, которому требуется служба каталогов Active Directory. В режиме рабочей группы происходит сбой подписи сообщения, так как служба каталогов Active Directory недоступна. Таким образом, сообщение попадает в очередь недоставленных сообщений и указывается причина сбоя, например "Неправильная подпись".

Чтобы обойти эту проблему, можно отключить систему безопасности. Это можно сделать, задав параметр Mode = None , чтобы он работал в режиме рабочей группы.

Как вариант можно получить MsmqTransportSecurity из свойства Transport и присвоить ему значение Certificate, а затем задать сертификат клиента.

Еще одним обходным путем является установка MSMQ с интеграцией Active Directory.

Q: При отправке сообщения с привязкой по умолчанию (включена безопасность транспорта) в Active Directory в очередь, я получаю сообщение "Внутренний сертификат не найден". Как устранить эту проблему?

A: Это означает, что сертификат в Active Directory для отправителя необходимо обновить. Для этого откройте панель управления, Администрирование, Управление компьютером, щелкните правой кнопкой мыши MSMQ и выберите Свойства. Перейдите на вкладку Сертификат пользователя и нажмите кнопку Продлить .

Q: Когда я отправляю сообщение с помощью Certificate и указываю используемый сертификат, я получаю сообщение "Недопустимый сертификат". Как устранить эту проблему?

A: Хранилище сертификатов локального компьютера нельзя использовать в режиме сертификатов. Необходимо скопировать сертификат из хранилища сертификатов компьютера в хранилище текущего пользователя с помощью оснастки сертификатов. Чтобы получить оснастку сертификатов, выполните следующие действия.

  1. Нажмите кнопку Пуск, выберите Выполнить, введите mmcи нажмите кнопку ОК.

  2. В консоли управления (МАЙКРОСОФТ) откройте меню Файл и выберите Добавить или удалить оснастку.

  3. В диалоговом окне Добавление и удаление оснастки нажмите кнопку Добавить .

  4. В диалоговом окне Добавление автономной оснастки выберите Сертификаты и нажмите кнопку Добавить.

  5. В диалоговом окне Оснастки "Сертификаты " выберите Моя учетная запись пользователя и нажмите кнопку Готово.

  6. Затем добавьте вторую оснастку Сертификаты, выполнив предыдущие шаги, но на этот раз выберите Учетная запись компьютера и нажмите кнопку Далее.

  7. Выберите Локальный компьютер, а затем нажмите кнопку Готово. Теперь сертификаты можно перетаскивать из хранилища сертификатов компьютера в хранилище текущего пользователя.

Q: Когда моя служба считывает данные из очереди на другом компьютере в режиме рабочей группы, я получаю исключение "доступ запрещен".

A: В режиме рабочей группы, чтобы удаленное приложение могло получить доступ к очереди, приложение должно иметь разрешение на доступ к очереди. Добавьте "Анонимный вход" в список управления доступом (ACL) очереди и предоставьте ей разрешение на чтение.

Q: Когда клиент сетевой службы (или любой клиент без учетной записи домена) отправляет сообщение в очереди, отправка завершается ошибкой с недопустимым сертификатом. Как устранить эту проблему?

A: Проверьте конфигурацию привязки. В привязке по умолчанию включена безопасность транспорта MSMQ для подписи сообщения. Отключите ее.

Удаленное получение транзакций

Q: Если у меня есть очередь на компьютере A и служба WCF, которая считывает сообщения из очереди на компьютере B (сценарий получения с удаленными транзакциями), сообщения не считываются из очереди. Данные трассировки указывают на сбой получения с сообщением "Транзакция не может быть импортирована". Что можно сделать, чтобы устранить эту проблему?

A: Это может быть вызвано тремя причинами.

  • В режиме домена для удаленного получения транзакций требуется доступ к сети координатора распределенных транзакций (Майкрософт) (MSDTC). Это можно включить с помощью команды Добавление и удаление компонентов.

    Снимок экрана: включение сетевого доступа DTC.

  • Проверьте режим проверки подлинности для взаимодействия с диспетчером транзакций. Если вы находитесь в режиме рабочей группы, необходимо выбрать параметр "Не требуется проверка подлинности". Если вы находитесь в режиме домена, необходимо выбрать параметр "Требуется взаимная проверка подлинности".

    Включение транзакций XA

  • Убедитесь, что MSDTC находится в списке исключений в параметрах брандмауэра подключения к Интернету .

  • Убедитесь, что вы используете Windows Vista. MSMQ в Windows Vista поддерживает удаленное чтение с транзакцией. MSMQ в более ранних версиях Windows не поддерживает удаленное чтение в транзакциях.

Q: Если служба, считываемая из очереди, является сетевой службой, например на веб-узле, почему при чтении из очереди возникает исключение с отказом в доступе?

A: Доступ на чтение сетевой службы должен быть добавлен в список ACL очереди, чтобы обеспечить возможность чтения сетевой службы из очереди.

Q: Можно ли использовать службу активации MSMQ для активации приложений на основе сообщений в очереди на удаленном компьютере?

Ответ. Да. Для этого необходимо настроить службу активации MSMQ для выполнения в качестве сетевой службы, а также добавить доступ сетевой службы к очереди на удаленном компьютере.

Использование пользовательских привязок MSMQ с включенным ReceiveContext

При использовании пользовательской привязки MSMQ с ReceiveContext включенной обработкой входящего сообщения используется поток пула потоков, так как собственный MSMQ не поддерживает завершение ввода-вывода для асинхронных ReceiveContext приемов. Это связано с тем, что при обработке такого сообщения используются внутренние транзакции для ReceiveContext и MSMQ не поддерживает асинхронную обработку. Чтобы обойти эту проблему, можно добавить в конечную SynchronousReceiveBehavior точку для принудительной синхронной обработки или задать значение MaxPendingReceives 1.