Допустим, у нас есть
- Клиентский узел с исходящей службой шлюза HTTP
- Узел сервера с входящей службой шлюза HTTP
Я рассматриваю ситуацию, когда MSMQ сам по какой-то причине останавливается на клиентском узле. В текущей реализации HTTP-шлюз Rebus перехватит исключение.
Что вы думаете о том, что исключение MessageQueueException, вместо того, чтобы просто перехватить, могло быть отправлено на серверный узел и помещено в очередь ошибок? (имя очереди ошибок можно получить из заголовков)
Таким образом, без дополнительной инфраструктуры сервер будет знать, что у клиента есть проблема, чтобы кто-то мог отреагировать.
ОБНОВЛЕНИЕ:
Я предположил, что возникнут проблемы, описанные в ответе. Надо было объяснить свой сценарий глубже :) Извините за это. Вот:
Я собираюсь изменить HTTP-шлюз таким образом, чтобы InboundService мог делать и то, и другое - отправлять и получать сообщения. Таким образом, OutboundService будет единственным, кто инициирует соединение (периодически, например, раз в 5 минут), чтобы получать новые сообщения с сервера и отправлять свои сообщения на сервер. Это связано с тем, что клиентский узел рассматривается не как сервер, а как один из многих клиентов, находящихся за NAT.
Действительно, сам сервер не заинтересован в работоспособности клиента, но я подумал, что вместо создания отдельной службы оповещения на стороне клиента, которая будет использовать код HTTP-шлюза HTTP-шлюз, HTTP-шлюз itelf может это сделать, поскольку он довольно в бизнес шлюза HTTP, чтобы обе стороны работали.
Что делать, если клиент вообще не может связаться с сервером?
Поскольку MSMQ был бы мертв, я подумал об использовании внутрипроцессного автономного объекта постоянной очереди вроде этого http://ayende.com/blog/4540/building-a-managed-persistent-transactional-queue (просто пример реализации, я не уверен, какая у него лицензия) для агрегирования исключения на стороне клиента до тех пор, пока сервер не станет доступным.
И как часто клиент будет уведомлять сервер, на котором произошла ошибка?
Я не уверен насчет этой части - я думал, что это может быть связано с запланированным временем синхронизации сообщений, например, один раз в 5 минут, но что в случае, если не будет запланированного времени, как в текущей реализации (цикл while (true))? Может быть просто конфигом поставить?
Мне нравится иметь последовательную стратегию обработки ошибок, которая обычно связана с обычным старым журналом NLog
Поскольку клиентские узлы будут находиться в Интернете за NAT, стандартные методы мониторинга работать не будут. Я думал об использовании очереди в качестве транспорта NLog, но, поскольку MSMQ был бы мертв, это не сработало.
Я также думал об использовании HTTP в качестве транспорта NLog, но на стороне сервера для этого потребовалась бы очередь (не совсем, но я бы хотел сохранить ее в очереди), поэтому мы вернулись к sbus и HTTP-шлюзу ... такой транспорт NLog будет быть де-факто клоном HTTP-шлюза.
ОБНОВЛЕНИЕ 2: HTTP как транспорт NLog (под транспортом я имею в виду цель) также потребует очереди на стороне клиента, как я описал в разделе «Что делать, если клиент вообще не может связаться с сервером?» раздел. Это будет клон HTTP-шлюза, встроенный в NLog. Безумие :)
Все дело в том, что клиент ненадежен, поэтому я хочу иметь всю информацию о клиенте на стороне сервера и регистрировать ее там.
ОБНОВЛЕНИЕ3
Альтернативным решением может быть создание отдельной службы, которая, однако, будет частью HTTP-шлюза (например, OutboundAlertService). Тогда были бы выполнены три цели:
- общий код цикла отправки
- не требуется дополнительная серверная инфраструктура
- нет отрицательного влияния на OutboundService (нет сложности с добавлением в него очереди внутри процесса)
Он не будет принимать исключения из OutboundService, но вместо этого будет периодически проверять MSMQ.
Еще одним альтернативным решением было бы просто использовать в качестве цели NLog другую очередь, кроме очереди MSMQ, но это уродливое излишество.