11

场景
应用程序的数据库已关闭。这会导致任何负责将重要数据提交到数据库的参与者无法获得连接

首选行为重要数据在将来某个时间
恢复时被写入数据库。

当前实现
Actor 捕获 DBException,将数据包装在 DBWriteFailed 案例类中,并将消息发送给其主管。然后,主管使用 system.scheduler.scheduleOnce(...) 安排在未来某个时间(例如 1 分钟)进行另一次写入,这样我们就不会在等待数据库恢复时绕圈子太多。

这个实现当然有效,但我觉得可能有更好的方法。

  • 当提交参与者在成功提交后必须响应原始发送者时,协议会变得有点混乱。
  • 发送到提交参与者的常规消息流不会以任何方式受到限制,并且参与者将愉快地处理新消息,可能无法为每条消息连接到数据库。
  • 如果消息在此重试循环中被捕获的时间过长,提交参与者的邮箱将开始膨胀。提交这些数据很重要,但如果应用程序由于内存使用过多而停止或崩溃,这些都无关紧要。

我是一个 akka 新手,在主管策略方面我基本上没有经验,但我觉得我可以利用其中一个来处理一些重试逻辑。

akka 中是否有解决此类问题的通用方法?我是在正确的轨道上还是应该朝着不同的方向前进?

任何帮助表示赞赏。

4

2 回答 2

9

您可以使用Akka 断路器来减少连接尝试。我不会使用调度程序作为重试队列,而是在actor内部使用一个缓冲区(具有最大大小限制),并在断路器再次关闭时重试(onClose回调应该向自身actor发送消息)。另一种方法是将断路器与存储邮箱结合使用。

于 2012-12-17T08:53:06.103 回答
1

如果您计划在您的应用程序中实施完全故障转移

不。

不要将数据库故障转移责任冒泡到应用层。就您的应用程序而言,数据库应该刚刚启动并准备好接受读取和写入。

如果您的数据库经常出现故障,请花时间使您的数据库更加健壮(网络上已经有大量资源用于此:在网络上搜索“复制”、“高可用性”、“负载平衡”和“集群”等术语',并从highscalability.com上其他人的战争故事中学习)。这完全取决于您的数据库中断的原因是什么(例如,我曾经将数据库主机上的 NIC 用尽,并通过在线上启用 GZIP 间歇性地“修复”了问题)。

如果你走这条路,你会很高兴你坚持关注点分离。

如果您计划实施奇怪的重试逻辑并处理 DB 掉电

如果您不希望您的应用程序成为替代数据库,那么Patrik 的回答是最好的选择。

于 2012-12-17T08:07:05.257 回答