私はかつて .NET で Crawler を作成しました。スケーラビリティを向上させるために、.NET の非同期 API を利用してみました。
System.Net.HttpWebRequest には非同期 API BeginGetResponse/EndGetResponse があります。ただし、この API のペアは、HTTP 応答ヘッダーと、HTTP 応答コンテンツを抽出できる Stream インスタンスを取得するためのものです。したがって、私の戦略は、BeginGetResponse/EndGetResponse を使用して非同期的に応答ストリームを取得し、次に BeginRead/EndRead を使用して応答ストリーム インスタンスからバイトを非同期的に取得することです。
クローラーがストレステストに行くまで、すべてが完璧に見えます。ストレス テストでは、クローラーのメモリ使用量が高くなります。WinDbg+SoS でメモリをチェックしたところ、多くのバイト配列が System.Threading.OverlappedData インスタンスによって固定されていることがわかりました。インターネットで検索した後、Microsoft からこの KB http://support.microsoft.com/kb/947862を見つけました。
KB によると、非同期 I/O の数には「上限」があるはずですが、「推奨される」境界値はわかりません。したがって、私の目には、この KB は何の役にも立ちません。これは明らかに .NET のバグです。最後に、応答ストリームから非同期でバイトを抽出するという考えを捨てて、同期的な方法でそれを行う必要があります。
ドット ネット ソケット (Socket.BeginSend / Socket.BeginReceive / NetworkStream.BeginRead / NetworkStream.BeginWrite) で非同期 IO を許可する .NET ライブラリには、非同期 IO で未処理のバッファー (送信または受信) の量に上限が必要です。 .
ネットワーク アプリケーションは、ポストする未処理の非同期 IOの数に上限を設定する必要があります 。
編集:いくつかの疑問符を追加してください。
Socket と NetworkStream で非同期 I/O を実行した経験のある人はいますか? 一般的に言えば、本番環境のクローラーは、同期または非同期でインターネットとの I/O を行いますか?