处理长时间运行任务的良好API架构是什么?

3
我正在尝试实现一个基于ASP.NET Core的Web服务,通过ARM模板和Azure SDK for .NET部署Azure资源。然而,根据我的测试结果,某些操作可能需要三到四分钟才能完成。我没有设计过这样长时间执行任务的API。
因此,我考虑采取以下做法:
1. 当API接收到请求来部署资源时,将请求信息放入队列中。 2. 返回200,并为调用者提供票据号以便可以通过调用另一个端点来监视进度。 3. 使用webjob创建资源请求,并更新数据库中的信息。 4. 当调用者调用获取资源部署进度的端点时,我可以提供更新的信息(成功或失败)。
我对这种架构不确定,因为我之前从未做过类似的事情。我正在考虑使用Azure Queues对传入请求进行组织,使用Azure Tables放置有关请求的信息,如部署的详细情况,并使用Azure WebJobs在其制作时执行请求的创建。
这是一个足够好的架构吗?还是应该考虑使用其他技术或模式来完成这个任务?我不确定如何处理这种情况,欢迎您提出任何意见。

  1. 返回一个 202 Accepted,以明确地表示“嘿,我有你的东西,稍后会处理它”。不要返回一个票据号码,而是在结果中添加一个 Location 头部,并在你大致知道客户端应该“回调”的时间时添加一个 Retry-after 头部。客户端在 Location 不再返回 404 时,应该尝试呈现结果或启动处理这些结果的任何逻辑。
- evilSnobu
2个回答

1
  1. 我会返回状态码200并提供一个票据号码给调用者,以便他们可以通过调用另一个端点来监视进度。

应该返回202 Accepted来明确地表示“嘿,我已经收到你的请求了,稍后我会处理它。”

不要返回票据号码,而是在结果中添加一个Location头部,如果你大概知道客户端应该“回调”什么时候,可以添加一个Retry-after头部。

客户端方面,当Location URL不再返回404时,客户端UI应该尝试呈现结果,或者——如果没有UI——启动处理这些结果的逻辑。

我正在考虑使用Azure队列来组织传入的请求[...]

我赞同这个决定。否则,你将不得不从头开始重新实现耐久性、重试和恶意参与者处理,我们都知道最好的代码是别人的代码。

使用Azure队列,你需要自己实现毒消息逻辑,而Service Bus已经为你提供了这个功能。


0

这个问题正在征求意见,可能会被关闭。但在此之前,这是一个非常合理的计划,可以实现你想要完成的目标。我个人实现了一个非常类似的架构,在重负载下表现良好。以下是一些指针:

  • 确保选择适当的队列实现。你的选择是Service Bus Queues或Storage Queues。你可以在这里找到一个很好的比较

  • Azure Tables是便宜(并且可以非常快速)扩展的存储。但你只有一个分区键和一个行键可用。如果这对你想做的事情足够了,那太好了!否则考虑使用CosmosDB Tables或Azure SQL DB等其他方案。

  • 对于长时间运行的处理,请考虑如果你的WebJob崩溃并且你必须重新启动处理队列消息会发生什么。如果有多个处理阶段不应该重复,你需要为此进行规划。否则,ServiceBusTrigger内置了很好的重试逻辑。


但是你只有一个分区键和一个行键可以使用,你能再详细解释一下吗? - adamasan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接