2

新しい ASP.NET Web API に基づいて Web API を作成しています。複数のデータセットを同時に送信する人々を処理する最善の方法を理解しようとしています。100,000 件のリクエストがある場合は、一度に 1,000 件を送信できるようにするとよいでしょう。

Contacts Controller に create new Contact メソッドがあるとします。

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 に非常に似ています。これはアトミック操作です。PUT の個々の呼び出しの代わりに is を使用すると、連絡先はあまり RESTfull ではない可能性があります (ただし、これについては議論の余地があります)。

HTTP パイプラインを調べて、同じソケットの複数の PutContact リクエストを送信することをお勧めします。リクエストごとに、その 1 つのリクエストの標準 HTTP ステータスを返すことができます。

過去に SOAP を使用してバッチ更新を実装したことがありますが、システムに負荷がかかっているときに予期しない問題がいくつか発生しました。注意しないと同じ問題に遭遇すると思います。

  1. たとえば、バッチ更新の途中でデータベースがタイムアウトし、障害、信頼性、トランザクションなどの面で地獄が崩壊する可能性があります。そして、貧弱なクライアントは実際に更新されたものを把握して再試行する必要がありました.
  2. 更新するレコードが多すぎると、時間がかかりすぎて HTTP 要求がタイムアウトになりました。それはワームの別の缶を開けました。
  3. もう 1 つの懸念は、更新中にどれだけのデータを受け入れるかということでした。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 を実行して、ジョブのステータスを実行中および完了に更新できます。

処理されたばかりのデータをナビゲートしたり、エラーに対処したりするには、別のサービスが必要になります。

バックグラウンド プロセスは、検証エラーを許容する必要がある場合があります。そうでない場合、またはサービスが検証を行う場合 (応答時間を保証できないデータベース呼び出しなどを行っていないと仮定して)、クライアントが問題を修正してリクエストを再送信するのに十分な情報を含む CreateJobResponse のような構造を返すことができます。時間のかかる検証を行う必要がある場合は、バックグラウンド プロセスで行い、ジョブを失敗としてマークし、クライアントがエラーを修正してリクエストを再送信できるようにする情報でジョブを更新します。これは、クライアントがジョブが失敗したという事実で何かを実行できることを前提としています。

Create メソッドがジョブ リクエストを多くの小さな「ジョブ」に分割する場合、それがアトミックではない可能性があるという事実に対処する必要があり、ジョブが正常に完了したかどうかを監視するために多くの課題が発生します。

于 2012-03-01T19:15:39.837 に答える
0

PUT 操作は、リソースを置き換えることになっています。通常、これは単一のリソースに対して行いますが、コレクションに対して行う場合、元のコレクションを渡されたデータのセットに置き換えることになります。そうするつもりかどうかはわかりませんが、コレクションのサブセットを更新しているだけだと思います。その場合、PATCH メソッドの方が適切です。

最後に、バッチ リクエストに応答するための最適な方法についてのヒントを教えてください。300回のうち4回失敗したら?

それは本当にあなた次第です。応答は 1 つしかないため、200 OK または 400 Bad Request を送信して詳細を本文に入れることができます。

于 2012-03-01T18:45:47.217 に答える