脚本
应用程序的数据库已经关闭。这导致任何负责将重要数据提交给DB的任何actor都无法获得连接
首选行为
重要数据在重新启动时写入数据库 将来的某个时候。
目前的实施
该actor捕获DBException,将数据包装在DBWriteFailed案例类中,并将消息发送给其主管。然后,主管使用system.scheduler.scheduleOnce(...)在将来某个时间(例如1分钟)安排另一次写入,这样我们就不会在等待DB重新启动时过多旋转。
这种实现当然有效,但我觉得可能有更好的方法。
- 当提交的actor在成功提交后必须响应原始发送者时,协议会变得有点麻烦。
- 对提交actor的常规消息流不受任何限制,并且actor会愉快地处理新消息,可能无法为每个消息连接到DB。
- 如果消息在此重试循环中被捕获的时间过长,则提交的actor的邮箱将开始出现气球。提交此数据非常重要,但如果应用程序因内存使用过多而导致停止或崩溃,则无关紧要。
我是一名akka新手,在涉及主管策略方面我基本缺乏经验,但我觉得我可能能够利用其中一个来处理一些重试逻辑。
在akka中有一个共同的方法来解决这样的问题吗?我是在正确的轨道上还是我应该向不同的方向前进?
任何帮助表示赞赏。
您可以使用 Akka断路器 减少连接尝试。不使用调度程序作为重试队列,我将在actor内部使用缓冲区(具有最大大小限制),并在断路器再次关闭时重试那些(onClose回调应该向自己的actor发送消息)。另一种方法是将断路器与a组合 存放邮箱。
您可以使用 Akka断路器 减少连接尝试。不使用调度程序作为重试队列,我将在actor内部使用缓冲区(具有最大大小限制),并在断路器再次关闭时重试那些(onClose回调应该向自己的actor发送消息)。另一种方法是将断路器与a组合 存放邮箱。
如果您计划在应用中实施完全故障转移
别。
不要将数据库故障转移责任限制在应用层中。就您的应用而言,数据库应该刚刚启动并准备好接受读写操作。
如果您的数据库经常出现故障,请花时间让您的数据库更加健壮(网络上已有大量资源用于此:在网络上搜索“复制”,“高可用性”,“负载平衡”和“群集”等术语',并从他人的战争故事中学习 highscalability.com)。这一切都取决于数据库中断的原因(例如,我曾经在数据库主服务器上最大化了网卡,并通过在线路上启用GZIP来间歇性地“解决”问题)。
如果沿着这条路走下去,你会很高兴你坚持分离。
如果您计划实施奇数重试逻辑并处理数据库欠压
如果您不希望您的应用成为替代数据库,那么 帕特里克的回答 是最好的方式。