【问题标题】:How to implement blocking queue-like SQL mechanism如何实现类似阻塞队列的SQL机制
【发布时间】:2020-09-26 09:52:59
【问题描述】:

我的程序是一个通知服务,它基本上接收http请求(客户端发送通知)并将它们转发到设备。

我希望它按以下方式工作:

  1. 接收客户端通知请求
  2. 将其保存到数据库中(是的,我需要这一步,这是强制性的)
  3. 异步线程监视数据库中的新请求
  4. 异步线程将它们转发到目标(设备)。

在这种情况下,程序可以在步骤 2) 之后立即发送客户端确认。 因此,不等待目的地响应(设备响应时间可能太长)。

如果我将客户端通知存储在内存中,我会使用 BlockingQueue。但我需要将我的通知保存在数据库中。另外,我不能使用消息队列,因为客户端希望其他端点发送通知。

帮我设计出这种机制的架构。

PS 在 Java、Postgresql 中

【问题讨论】:

    标签: java spring postgresql


    【解决方案1】:

    以下是一些可以导致解决方案的想法:

    1. 可能第 2 步是强制性的,以确保请求保持不变,以便对其进行查询。所以我们在这里谈论一些“数据模型”。 考虑到这一点,如果您“在步骤 2 之后立即”“发送”确认 - 如果稍后您想对这些数据执行一些操作(例如,将其发送到某处)并且此操作没有成功,该怎么办。你把它存储在磁盘上?如果磁盘已满怎么办?

    最重要的问题是,在这种情况下,您的数据模型(在数据库中)会发生什么变化?数据库中的条目应该仍然存在还是整个“逻辑”操作都失败了?这是您应该弄清楚的,具体取决于实际系统,答案可能会有所不同。

    最“严格”的解决方案会以以下(示意图)方式使用事务:

    
    tr = openTransaction()
    try {
       saveRequestIntoDB(data);
       forwardToDestination(data);
       tr.commit();
    } catch(SomeException ex) {
       tr.rollback();
    }
    

    使用这种设计,如果在“saveRequest”步骤中出现问题 - 好吧,什么都不会发生。如果数据存储在 db 中,但 forwardToDestination 失败 - 那么事务将被回滚并且记录不会存储在 DB 中。

    如果所有操作都成功 - 事务将被提交。

    1. 现在看起来您仍然可以在第 4 步中使用消息传递系统。发送消息可以很快,并且不会给整个请求增加任何重大开销。

    另一方面,好处是显而易见的: - 谁听这些“通知”?如果你发送了一些东西而只有一个服务应该接收并处理通知,你如何确保其他人不会收到它?您将如何实现相反的效果 - 如果所有服务都应该获得通知并独立处理它会怎样?

    这些设施已经由任何下降消息系统实现。

    1. 我不太明白这句话:

    我不能使用消息队列,因为客户端希望其他端点发送通知。

    由于整个流程是由客户的请求发起的,我在这里看不到任何矛盾。从rest端点调用的代码(毕竟这是一个应该由你实现的逻辑入口点)可以调用数据库,持久化数据,然后发送通知......

    【讨论】:

    • 1.我将请求保存到数据库以确保弹性:客户端发送通知请求,服务回答他:“即使出现任何可能的故障,您的通知最终也会转发到设备。”所以客户确定,一段时间后通知会在设备中弹出。
    • 2.让我们声明只有一台设备正在收听通知
    • 3.客户端通过 rest 向 Notification 服务发送通知请求,然后 Notifications 服务通过 rest 将它们转发到设备。 (如您所见,此流程中没有消息队列)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-01
    • 1970-01-01
    • 2014-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多