Реализация WebHooks с помощью ServiceStack

В настоящее время я работаю над сервисом REST, позволяющим контролировать и контролировать некоторые физические устройства.

Соответствующий REST API в значительной степени основан на принципах и идеях, которые вы можете найти в следующей статье: " Управление и мониторинг устройств с помощью REST ".

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

Таким образом, всякий раз, когда происходит событие, моя служба выполняет обратный вызов API REST для каждого подписчика, чтобы уведомить его.

Мой вопрос сейчас:

Как правильно реализовать этот сценарий с помощью ServiceStack (версия 3.9.71)?

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

Нужно ли реализовывать все с нуля (используя, например, ServiceStack, размещенный на RedisMqServer) или уже есть что-то, что идет дальше в моем направлении? Я погуглил без особого успеха.

2 ответа

Решение

Я считаю, что вы подходите к решению с неправильного конца. Вы можете определенно использовать ServiceStack для выполнения вызовов Web Hook, предпочтительно в формате JSON.

Что вам действительно стоит изучить, так это очереди сообщений, поскольку они обладают всеми характеристиками, необходимыми для реализации вызовов Web Hook (долговечность, политики очистки сообщений, фильтрация сообщений, политики доставки, политики маршрутизации, критерии очередей).

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

Рабочий процесс, за которым событие будет следовать до того момента, когда будет вызван Web Hook:

  1. Событие происходит в системе; чтобы гарантировать, что Web Hook будет вызван, вы должны длительно поставить в очередь событие для обработки (через служебную шину, такую ​​как RabbitMq, MassTransit, NServiceBus и т. д.). Давайте назовем целевую очередь EventsQueue
  2. Затем приложение будет подключаться к EventsQueue и обрабатывать сообщения:
    1. Выяснение, кто подписался на это конкретное событие
    2. Для каждого подписчика поставьте в очередь новое сообщение, содержащее копию данных события и подробностей подписчика (например, URL обратного вызова) в WebHookQueue с начальным временем жизни (срок действия сообщения).
  3. Затем приложение будет подключаться к WebHookQueue и обрабатывать сообщения с помощью обратных вызовов.

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

Вот отличная статья, в которой подробно описывается, как использовать TTL (Time To Live) для повторной отправки сообщений через определенные промежутки времени.

Я бы выбрал несколько иной подход:

  • Создайте разные очереди на уровне повторных попыток (например, WebHookRetryQueue = недоставленная очередь WebHookQueue, WebHookRetryLvl1Queue = TTL 5 минут, WebHookRetryLvl2Queue = TTL 15 минут). Хитрость заключается в том, чтобы установить очередь недоставленных сообщений этих очередей на уровне повторных попыток в WebHookQueue и оставить в очереди сообщения, срок действия которых истекает (имеется в виду, что после истечения срока действия сообщения в очереди на уровне повторных попыток оно помещается обратно в WebHookQueue).
  • Затем вам нужно будет отслеживать текущий уровень повторных попыток для сообщений в WebHookRetryQueue, а затем помещать сообщение в очередь на соответствующий уровень повторных попыток - после истечения срока действия TTL вставляется обратно в WebHookQueue.

Пример рабочего процесса: WebHookQueue с максимальным числом повторных попыток: 2, TTL: 1 день

Пример сообщения: {'event_type': 'Email_Reply', 'callback_url': '...', 'reply_level': 0, 'queued_at': '2013-09-25T22:00:00Z', данные: 'json encoded'}

Сообщение -> WebHookQueue (сбой) -> WebHookQueue (сбой) -> WebHookRetryQueue (вкл. Reply_level=1 + enqueue) -> WebHookRetryLvl1Queue (5 минут истечения) -> WebHookQueue (сбой) -> WebHookQueue (сбой) -> incr. reply_level=2 + enqueue) -> WebHookRetryLvl2Queue (истечение 15 минут) -> WebHookQueue (сбой) -> WebHookQueue (сбой) -> WebHookRetryQueue (удаление сообщения)


редактировать

Нажмите здесь, чтобы посмотреть на простой пример с использованием WebHookQueue и WebHookRetryQueue с использованием TTL уровня сообщений RabbitMQ. Из-за уровня сообщения TTL; нет необходимости создавать разные очереди на уровне повторных попыток - что может быть необходимо для менее популярных очередей сообщений.


Если бы вам пришлось реализовать такую ​​очередь с возможностью истечения отдельных сообщений (не с помощью политик очистки) или планировать сообщения заранее с возможностью перепланирования / истечения срока действия - вам, скорее всего, пришлось бы выбирать очереди на основе базы данных.

Вот отличная статья о CodeProject о создании такой высокопроизводительной очереди для MSSQL Server (переносимой на другие базы данных, такие как MySql/Postgresql/Mongodb/Couchbase и т. Д.)

Надеюсь, вы нашли эту информацию полезной.

ServiceStack.Webhooks - это новая платформа для простого добавления веб-крючков в ваши сервисы, независимо от того, какой архитектурный шаблон вы хотите использовать. Вы можете просто создать свой собственный плагин.

Другие вопросы по тегам