我正在开发一个接受用户请求的REST服务。每个用户请求代表繁重的计算工作。我不希望计算工作阻止REST服务。我的设计是将用户请求包装为任务(具有唯一的任务ID)并推送到Kafka。后台工作者订阅Kafka并处理任何传入的任务。 REST服务将任务保存到数据库中,将任务ID推送到Kafka,然后立即返回任务ID。用户使用任务ID保持轮询任务状态。
这个设计很好。但我仍然不知道如何处理一个场景:如果服务在将任务保存到数据库后立即崩溃(例如,进程停止,容器退役),但在将任务ID推送到Kafka之前,则永远不会处理该任务
这是一个很少发生的边缘情况。但在服务重启或重新部署期间,可能会发生这种情况。那么如何才能将这两个操作(保存到数据库并推送到Kafka)原子化?或者有什么解决方法吗?
答案 0 :(得分:0)
鉴于您正在处理消息,此过程中应该发生的最后一件事是应该确认消息。所以,让我们假设在最佳流状态下发生以下情况:
名义流量
非名义流量
您的问题涉及6到7之间的中断。如果此处发生中断,则根据名义流量,将不会发送确认,并且将在队列的头部替换该消息。
需要做的是在步骤2和3之间调整标称处理顺序。让工作人员在开始处理消息之前检查数据库中是否有现有结果。如果已经计算了结果,它可以跳到步骤7并从那里继续。