使用REST服务和Kafka将后台CPU密集型工作卸载到后台工作者

时间:2018-02-08 07:16:28

标签: rest asynchronous apache-kafka message-queue

我正在开发一个接受用户请求的REST服务。每个用户请求代表繁重的计算工作。我不希望计算工作阻止REST服务。我的设计是将用户请求包装为任务(具有唯一的任务ID)并推送到Kafka。后台工作者订阅Kafka并处理任何传入的任务。 REST服务将任务保存到数据库中,将任务ID推送到Kafka,然后立即返回任务ID。用户使用任务ID保持轮询任务状态。

这个设计很好。但我仍然不知道如何处理一个场景:如果服务在将任务保存到数据库后立即崩溃(例如,进程停止,容器退役),但在将任务ID推送到Kafka之前,则永远不会处理该任务

这是一个很少发生的边缘情况。但在服务重启或重新部署期间,可能会发生这种情况。那么如何才能将这两个操作(保存到数据库并推送到Kafka)原子化?或者有什么解决方法吗?

1 个答案:

答案 0 :(得分:0)

鉴于您正在处理消息,此过程中应该发生的最后一件事是应该确认消息。所以,让我们假设在最佳流状态下发生以下情况:

名义流量

  1. 代理将消息放入队列
  2. 工作人员提取消息
  3. 工作人员更新数据库中任务的状态
  4. 工人开始计算
  5. 工人完成计算
  6. 工作人员将结果存储在数据库中
  7. 工作人员将任务ID推送到Kafka (我不知道这究竟是什么)
  8. 工作人员向经纪人发送确认消息已完成的确认
  9. 代理会丢弃已成功处理的消息。
  10. 非名义流量

    您的问题涉及6到7之间的中断。如果此处发生中断,则根据名义流量,将不会发送确认,并且将在队列的头部替换该消息。

    需要做的是在步骤2和3之间调整标称处理顺序。让工作人员在开始处理消息之前检查数据库中是否有现有结果。如果已经计算了结果,它可以跳到步骤7并从那里继续。

相关问题