6

サードパーティのサーバーから情報を取得するためにサードパーティのサーバーを要求する必要がある .NET4 ベースのアプリケーションを開発しています。これらの HTTP リクエストを行うために HttpClient を使用しています。

短期間に 100 から 1000 のリクエストを作成する必要があります。これらのリクエストの作成を制限(定数などで定義)に制限して、他のサーバーが多くのリクエストを受信しないようにしたいと思います。

いつでも作成されるタスクの量を減らす方法を示すこのリンクを確認しました。

これが私の非機能的なアプローチです:

// create the factory
var factory = new TaskFactory(new LimitedConcurrencyLevelTaskScheduler(level));

// use the factory to create a new task that will create the request to the third-party server
var task = factory.StartNew(() => {
    return new HttpClient().GetAsync(url);
}).Unwrap();

もちろん、ここでの問題は、一度に 1 つのタスクが作成されたとしても、別のスケジューラで実行されるため、同時に多くの要求が作成されて処理されることです。スケジューラを HttpClient に変更する方法が見つかりませんでした。

この状況をどのように処理すればよいですか? 作成されるリクエストの量を特定の制限に制限したいのですが、これらのリクエストが完了するまでブロックしないでください。

これは可能ですか?何か案は?

4

4 に答える 4

1

保留中のリクエストの数をカウントできる HTTPClient のリクエスト/レスポンス パイプラインに配置する新しい DelegatingHandler を作成することを検討してください。

通常、単一の HTTPClient インスタンスを使用して複数のリクエストを処理します。HttpWebRequest とは異なり、HttpClient インスタンスを破棄すると、基になる TCP/IP 接続が閉じられるため、接続を再利用する場合は、HTTPClient インスタンスを再利用する必要があります。

于 2012-12-04T13:33:48.977 に答える
1

.Net 4.5 を使用できる場合、1 つの方法はTransformBlockTPL Dataflow から使用し、そのMaxDegreeOfParallelism. 何かのようなもの:

var block = new TransformBlock<string, byte[]>(
    url => new HttpClient().GetByteArrayAsync(url),
    new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = level });

foreach (var url in urls)
    block.Post(url);

block.Complete();

var result = new List<byte[]>();

while (await block.OutputAvailableAsync())
    result.Add(block.Receive());

を通じて、これを見る別の方法もありますServicePointManager。そのクラスを使用して、 (MaxServicePoints一度に接続できるサーバーDefaultConnectionLimitの数) と (各サーバーへの接続数) に制限を設定できます。この方法では、すべての を同時に開始できますがTask、実際に何かを行うのは限られた数だけです。ただし、 の数を制限するTask(たとえば、上で提案したように TPL データフローを使用する) 方が効率的である可能性が高くなります。

于 2012-11-29T18:38:30.183 に答える
0

まず、Web サイトに従ってワークロードを分割することを検討するか、少なくとも URL のリストを分割する方法を選択できる抽象化を公開する必要があります。たとえば、1 つの戦略は、yahoo.com、google.com などの第 2 レベル ドメインによるものです。

もう 1 つは、本格的なクロールを行っている場合は、代わりにクラウドでの実行を検討することをお勧めします。こうすることで、クラウド内の各ノードが異なるパーティションをクロールできます。「短期間」と言うと、すでに失敗の準備をしています。何を達成したいのか、明確な数字が必要です。

適切にパーティショニングすることのもう 1 つの重要な利点は、サイトが単純にスロットルしない場合に備えて、ピーク時にサーバーにアクセスしたり、ルーター レベルで IP 禁止のリスクを冒したりすることを回避できることです。

于 2012-11-29T04:13:12.813 に答える
0

固定された一連のスレッドを起動することを検討してください。各スレッドは、クライアントのネット操作をシリアルに実行します。スロットルするために特定のポイントで一時停止することもあります。これにより、ロードを具体的に制御できます。スロットル ポリシーを変更し、スレッド数を変更できます。

于 2012-11-29T04:25:51.357 に答える