カテゴリー:
スループットの増分
シナリオ:
複数の HttpWebRequestを、異なるイーサネット アダプターを介して同じホストに送信する必要があります。
覚えておくべきキー:
- リクエストは同じホストに送信されます。
- サービスポイントとして、ホストごとに組み込みの制限があります。
- System.Net.ServicePointManager.DefaultConnectionLimit を 100 に設定する (たとえば) か、同じ uri を持つ webrequest オブジェクトに対して webRequest.ServicePoint.ConnectionLimit = 50 を設定することによって、ホストへの同時リクエストの数を活用できます。 ソース:
サンプルコード:
Gist (Target Framework .Net 2.0) を完了します。
Uri url = new Uri("https://d585tldpucybw.cloudfront.net/docs/default-source/fiddler/fiddler4setup.exe?sfvrsn=80");
ServicePoint sp = ServicePointManager.FindServicePoint(url);
sp.BindIPEndPointDelegate = delegate (
ServicePoint servicePoint,
IPEndPoint remoteEndPoint,
int retryCount)
{
// If IPs referenced in localpoint does not exists, this delegate retries a 7000+ times in few seconds, blocking other threads. Take care!!!
Console.WriteLine("Retry count segment " + segmentEndPoint.segNumber + " is " + retryCount + " for eth with ip " + segmentEndPoint.ipEndPoint);
//Console.WriteLine("ip: " + segmentEndPoint.ipEndPoint);
if (retryCount < 200)
{
return segmentEndPoint.ipEndPoint;
}
else
{
return null;
}
};
sp.ConnectionLimit = 5;
sp.ConnectionLeaseTimeout = 0;
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Proxy = null; // if not set, HttpWebRequest searches system-wide proxy settins which takers 2-8 seconds!
webRequest.ConnectionGroupName = segmentEndPoint.segNumber + "hey";
webRequest.KeepAlive = false;
Console.WriteLine("ServicePoint: {0}, Thread: {1}", webRequest.ServicePoint.GetHashCode(), segmentEndPoint.segNumber);
var response = webRequest.GetResponse();
response.Close();
やってみたいです:
webreq1 ----- 経由で送信 ------- eth1
webreq2 ----- 経由で送信 ------- eth2
webreq3 ----- 経由で送信 ---- --- eth3
何が起こっている:
- webreq1 --- 接続を介して送信する場合 ---- eth1
- webreq2 -- 接続経由で送信 ---- eth1 (これは eth2 にバインドされています)
- webreq3 -- 接続経由で送信 ---- eth1 (これは eth3 にバインドされています)
- webRequest.ServicePoint.GetHashCode() は、すべての Web リクエストに対して同じハッシュを提供します。
問題 (未解決):
- 各 Webrequest は同じ servicepoint を使用していますが、HttpWebRequest ごとに ServicePoint の BindIPdelegate を介して異なるイーサネット接続を使用するように明示的に設定されています。
問題 (解決済み):
- 異なるスレッドの Web リクエストから同じホストへの複数のリクエスト。(servicepoint.ConnectionLimit を設定することで解決)(上記のソース)。
さらなる解決策 (解決されない場合は実装予定):
- Raw ソケットの使用。
- 同じ servicemanager-servicepoint シナリオに依存する場合、このソリューションは機能しない可能性があります。
要求された提案。よろしく。デブプラシャント。