MSMQ Peek Permissions Only (то есть без прав получения) - PullRequest
1 голос
/ 01 октября 2011

Сводка (tl; dr): Мы пытаемся настроить очередь с Peek доступом, но не Receive доступом для целей тестирования (поэтому запрос Receive завершится неудачно, ноPeek будет успешным), но кажется, что MSFT сделал это более трудным, чем ожидалось.

Справочная информация: У нас есть локальная частная очередь MSMQ, из которой один процесс получает и обрабатывает (/ потребляет)) Сообщения.В некоторых ситуациях обработка не может быть завершена, и сообщение остается в очереди (например, переадресация получателя временно в автономном режиме).Поэтому был добавлен монитор, который просматривал очередь каждые ~ 10 минут и проверял, является ли сообщение вверху одинаковым или нет - если потребитель остановлен (то же сообщение вверху), монитор выдает сигнал тревоги, чтобы указать,что-то не так.

Чтобы заставить очереди останавливаться в целях тестирования (чтобы убедиться, что функция монитора работает), мы подумали, что просто удалим (но не deny ) Receiveразрешения из самой очереди, но все равно позволяют Peek (перезапуск MSMQ и все для обеспечения новых разрешений), что в идеале позволило бы монитору Peek сообщений, не позволяя никому Receive (/ удалить) сообщения, «задерживающие» очередь и генерирующие тревогу.

Однако при тестировании этого сценария я столкнулся с исключением, которое, похоже, нарушает этот подход:

System.Messaging.MessageQueueException: Access to Message Queuing system is denied.
   at System.Messaging.MessageQueue.MQCacheableInfo.get_ReadHandle()
   at System.Messaging.MessageQueue.StaleSafeReceiveMessage(UInt32 timeout, Int32 action, MQPROPS properties, NativeOverlapped* overlapped, ReceiveCallback receiveCallback, CursorHandle cursorHandle, IntPtr transaction)
   at System.Messaging.MessageQueue.ReceiveCurrent(TimeSpan timeout, Int32 action, CursorHandle cursor, MessagePropertyFilter filter, MessageQueueTransaction internalTransaction, MessageQueueTransactionType transactionType)
   at System.Messaging.MessageQueue.Peek(TimeSpan timeout)

Этоуказывает (по крайней мере для меня), что Peek() внутренне вызывает ReceiveCurrent() и должен попробовать транзакционный Receive, чтобы он затем откатывался / прерывался после того, как это сделаноetting сообщение.Запустив .NET Reflector, я обнаружил, что все экземпляры Peek вызывают какой-то вариант Receive, поэтому другой Peek не поможет.Таким образом, похоже, что Receive разрешения необходимы , а также Peek, что кажется довольно глупым с точки зрения проектирования очереди.

Обратите внимание, что и потребитель, и мониториспользовать одну и ту же учетную запись (/ permissions), и изменение метода мониторинга (с использованием Peek) на данный момент не является жизнеспособным вариантом (поскольку это потребует значительных изменений требований, спецификаций и производственного кода,будет стоить больше, чем стоит) (хотя я думаю, вы могли бы предложить изменения методологии мониторинга в любом случае, если вам действительно это нужно, поскольку они могут быть полезны для других, если они сталкиваются с тем же самым).

Наконец,Вопрос: Есть ли лучший (или даже просто другой: p) путь к Peek в верхней части очереди без необходимости Receive разрешений?Или другой способ установки разрешений (через интерфейс разрешений, через код и т. Д.) Таким образом, что сам Receive завершается неудачно, но ReceiveCurrent и другие методы, необходимые для Peek, работают?

...