2

我正在基于新的 ASP.NET Web API 创建一个 Web API。我试图了解处理同时提交多个数据集的人的最佳方式。如果他们有 100,000 个请求,最好让他们一次提交 1,000 个。

假设我在联系人控制器中有一个创建新的联系人方法:

public string Put(Contact _contact)
{
    //add new _contact to repository
    repository.Add(_contact);

    //return success
}

允许用户“批量”提交新联系人的正确方法是什么?我在想:

public string BatchPut(IEnumerable<Contact> _contacts)
{
    foreach (var contact in _contacts)
    {
        respository.Add(contact);
    }
}

这是一个好习惯吗?这是否会解析带有 JSON 联系人数组的 GET 请求(假设它们的格式正确)?

最后,关于如何最好地响应批处理请求的任何提示?如果 300 次中有 4 次失败怎么办?

太感谢了!

4

2 回答 2

2

当您 PUT 集合时,您要么插入整个集合,要么替换现有集合,就好像它是单个资源一样。它与 GET、DELETE 或 POST 集合非常相似。这是一个原子操作。使用 is 作为对 PUT 联系人的个人调用的替代品可能不是非常 RESTfull(但这确实有待商榷)。

您可能希望查看HTTP 流水线并发送同一套接字的多个 PutContact 请求。对于每个请求,您都可以为该单个请求返回标准 HTTP 状态。

我过去使用 SOAP 实现了批量更新,当系统处于负载状态时,我们遇到了许多无法预料的问题。如果你不注意,我怀疑你会遇到同样的问题。

  1. 例如,数据库可能在批量更新的中间超时,并且在故障、可靠性、事务等方面都崩溃了。可怜的客户端必须弄清楚实际更新了什么,然后再试一次。
  2. 当要更新的记录太多时,HTTP 请求会因为我们花费的时间太长而超时。这打开了另一个蠕虫罐头。
  3. 另一个问题是我们在更新期间会接受多少数据?10MB 的联系人足够了吗?也许1MB?更大的缓冲区在内存使用和安全性方面有很多影响。

因此,我建议查看HTTP 流水线

更新

我的建议是将批量创建联系人作为异步过程处理。只需假设“作业”与“批量创建”过程相同。所以服务可能如下所示:

public class JobService
{
    // Post
    public void Create(CreateJobRequest job)
    {
       // 1. Create job in the database with status "pending"
       // 2. Save job details to disk (or S3)
       // 3. Submit the job to MSMQ (or SQS)
       // 4. For 20 seconds, poll the database to see if the job completed
       // 5. If the job completed, return 201 with a URI to "Get" method below
       // 6. If not, return 202 (aka the request was accepted for processing, but has not completed)
    }

    // Get
    public Job Get(string id)
    {
       // 1. Fetch the job from the database
       // 2. Return the job if it exists or 404
    }
}

使用队列中的内容的后台进程可以更新数据库,或者对服务执行 PUT 以将 Job 的状态更新为正在运行和已完成。

您将需要另一个服务来浏览刚刚处理的数据、解决错误等等。

您的后台进程可能需要容忍验证错误。如果没有,或者您的服务进行了验证(假设您没有进行无法保证响应时间的数据库调用等),您可以返回一个类似 CreateJobResponse 的结构,其中包含足够的信息供您的客户解决问题并重新提交请求。如果您必须进行一些耗时的验证,请在后台进程中进行,将作业标记为失败并使用允许客户端修复错误并重新提交请求的信息更新作业。这假设客户端可以对作业失败的事实做一些事情。

如果 Create 方法将作业请求分解为许多较小的“作业”,您将不得不处理这样一个事实,即它可能不是原子的,并且对监控作业是否成功完成提出了许多挑战。

于 2012-03-01T19:15:39.837 回答
0

PUT 操作应该替换资源。通常,您对单个资源执行此操作,但在对集合执行此操作时,这意味着您将原始集合替换为传递的数据集。不确定您是否打算这样做,但我假设您只是更新集合的一个子集,在这种情况下,PATCH 方法会更合适。

最后,关于如何最好地响应批处理请求的任何提示?如果 300 次中有 4 次失败怎么办?

这真的取决于你。只有一个响应,因此您可以发送 200 OK 或 400 Bad Request 并将详细信息放在正文中。

于 2012-03-01T18:45:47.217 回答