我目前正在研究一种REST服务,该服务可以控制和监视某些物理设备。

相应的REST API主要基于您可以在以下文章中找到的原理和思想:“Controlling and Monitoring Devices with REST”。

受监视和控制的设备可以生成一些客户端必须能够订阅的事件。我的想法是使用RESTful WebHooks实现该部分。

因此,无论何时发生事件,我的服务都会向每个订阅者进行REST API回调以通知它。

我的问题,现在:

使用ServiceStack(版本3.9.71 )来实现此方案的正确方法是什么?

我的服务必须能够将订阅排队并向订阅者分发事件。它还必须处理客户端宕机或无法访问的情况,并可能重试发送通知。

我是否必须从头开始实现所有功能(例如,使用ServiceStack托管的RedisMqServer),还是已经朝着我的方向前进?我已经在Google周围搜寻,但没有取得很大的成功。

最佳答案

我相信您是从错误的角度来寻求解决方案。您绝对可以使用ServiceStack进行Web Hook调用-最好使用JSON。

您真正应该研究的是消息队列,因为它们展现了实现Web Hook调用所需的所有特征(耐用性,消息清除策略,消息过滤,传递策略,路由策略,排队条件)

Read more about the properties of message queues on Wikipedia

事件的工作流程将一直进行到称为Web Hook的地步:

  • 系统中发生了一个事件。为了确保将调用Web Hook,您必须持久地使事件入队以进行处理(通过服务总线,例如RabbitMq,MassTransit,NServiceBus等)。让我们将目标队列称为EventsQueue
  • 然后,应用程序将连接到EventsQueue并通过以下方式处理消息:
  • 查找谁订阅了此特定事件
  • 对于,每个订阅者将一条包含事件数据和订阅者详细信息(例如回调URL)的副本的新消息加入具有初始生存时间(消息有效的时间)的WebHookQueue中。
  • 然后,应用程序将连接到WebHookQueue并通过进行回调来处理消息。

  • 因此,现在您有了一个基本的通知系统,该系统应确保至少发送一次消息。

    Here's a great article detailing how to use TTL (Time To Live) to retry messages at intervals

    我会采取一些不同的方法:
  • 创建不同的重试级别队列(例如WebHookRetryQueue = WebHookQueue的死信队列,WebHookRetryLvl1Queue = TTL 5分钟,WebHookRetryLvl2Queue = TTL 15分钟)。诀窍是将这些重试级别队列的死信队列设置为WebHookQueue,并将排队的消息保留为过期(这意味着一旦消息在重试级别队列中过期,它将被重新排队到WebHookQueue中)。
  • 然后,您需要在WebHookRetryQueue中的消息上跟踪当前的重试级别,然后将消息排队在适当的重试级别队列中-然后TTL过期,然后重新插入到WebHookQueue中。

  • 示例工作流程:最大重试次数为2的WebHookQueue,TTL:1天

    消息示例:{'event_type':'Email_Reply','callback_url':'...','reply_level':0,'queued_at':'2013-09-25T22:00:00Z',数据:'json编码' }

    消息-> WebHookQueue(失败)-> WebHookQueue(失败)-> WebHookRetryQueue(包括reply_level = 1 +入队)-> WebHookRetryLvl1Queue(5分钟到期)-> WebHookQueue(失败)-> WebHookQueue(失败)-> WebHookRetryQueue( incr.reply_level = 2 + enqueue)-> WebHookRetryLvl2Queue(15分钟到期)-> WebHookQueue(失败)-> WebHookQueue(失败)-> WebHookRetryQueue(放置消息)

    编辑

    Click here to look at simple example using a WebHookQueue and a WebHookRetryQueue using message level TTL's of RabbitMQ.由于消息级别TTL;不必创建其他的“重试级别”队列-对于功能较少的消息队列而言可能是必要的。

    如果您必须实现这样的队列,使其能够使单个消息到期(而不是通过清除策略),或者可以选择重新计划/到期选项来提前计划消息-您很可能不得不选择基于数据库的排队。

    Here's a great article on CodeProject on building such a high performance queue for MSSQL Server(可轻松移植到其他数据库,例如MySql/Postgresql/Mongodb/Couchbase等)

    希望您发现此信息有用。

    关于rest - 使用ServiceStack实现WebHooks,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18404392/

    10-10 11:14