【问题标题】:Offload CPU intensive work to background worker using REST service and Kafka使用 REST 服务和 Kafka 将 CPU 密集型工作卸载到后台工作人员
【发布时间】:2018-07-18 16:19:05
【问题描述】:

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

这个设计不错。但是我仍然不知道如何处理一种情况:如果在将任务保存到数据库后,但在将任务id推送到Kafka之前,服务立即崩溃(例如进程关闭,容器退役),那么任务将永远不会被处理。

这是一种可能很少发生的极端情况。但在服务重启或重新部署期间,可能会发生这种情况。那么我怎样才能使这两个操作(保存到数据库和推送到 Kafka)成为原子操作?或者有什么解决方法吗?

【问题讨论】:

  • 既然你使用的是 Kafka,那么用Kafka Streams API 来实现这个怎么样?你甚至不需要单独的数据库,因为 Kafka Streams 支持有状态的流处理。状态在内部保持不变,并通过写入 Kafka 的状态更改日志支持故障转移。

标签: rest asynchronous apache-kafka message-queue


【解决方案1】:

鉴于您正在处理一条消息,在此过程中应该发生的最后一件事是应该确认该消息。那么,让我们想象一下在最优流动状态下会发生以下情况:

标称流量

  1. 代理将消息放入队列
  2. worker 拉取消息
  3. worker 更新数据库中任务的状态
  4. 工人开始计算
  5. 工人计算完毕
  6. worker 将结果存储在数据库中
  7. worker 将 task id 推送到 Kafka (我不知道这到底是做什么的)
  8. worker 向代理发送消息已完成的确认
  9. 代理丢弃成功处理的消息。

非标称流量

您的问题涉及 6 到 7 之间的中断。如果中断发生在这里,根据标称流程,则不会发送确认,消息将被替换在队列的头部。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-18
    • 2014-04-14
    • 1970-01-01
    • 1970-01-01
    • 2015-07-22
    • 2013-05-14
    相关资源
    最近更新 更多