始める前に...これは本番用ではありません。この質問は、実際にテスト アプリケーションを作成しているときにのみ発生しました。私自身と別の開発者は、なぜ .net がこのようにパフォーマンスが悪いのかを調べていました。それはまったく.netではないかもしれません.OSかもしれません.誰かがトピックに光を当ててくれることを願っています:
私のテスト アプリケーションは、500 ~ 700 台の PC をシミュレートしてから、いくつかのポート ソフトウェアを実行しているオフィスに 500 ~ 700 台の物理マシンを積み上げて、TCP 経由で数百のデバイスに接続する本番アプリからの数百の接続を処理するように作成されました。
解決策を見つけることに興味がある場合は、テスト VS にコピーして貼り付けることができるサンプル チャンクを作成しました。非常にシンプルで再現しやすいです。
問題:
- 各ポートが開かれるたびに、次のポートが開くまでに時間がかかります。
- 数百のポートを作成した後、1 つのポートを作成するだけでも、CPU はかなりの負荷がかかります。
ノート:
- スレッド数は正常です...非常に少ないです(タスクマネージャーで16スレッド)
- 各ソケットを追加するため、ハンドル数も正常です。
- メモリ使用量も正常に見えます
- リフレクターを使用して .net ライブラリを調べ、Start() が何をしていたかを確認しました。通常のソケット呼び出しのように見えます。
サンプルコード:
using System;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
namespace SocketPerformanceTest
{
class Program
{
static void Main(string[] args)
{
const int socketToOpen = 500;
const int socketStartingPoint = 45000;
var sw = new Stopwatch();
for (var i = 0; i < socketToOpen; i++)
{
var thisPort = socketStartingPoint + i;
try
{
var listener = new TcpListener(IPAddress.Any, thisPort);
sw.Restart();
listener.Start();
sw.Stop();
Console.WriteLine("Started Port {0} in {1}", thisPort, sw.Elapsed);
}
catch{}
}
}
}
}
コンソール出力:
テスト アプリケーションが最初に起動すると、各ポートの実行時間がゆっくりと上昇することに注意してください。Stopwatch は Start() メソッドをラップします。
Started Port 45000 in 00:00:00.0086440
Started Port 45001 in 00:00:00.0131427
Started Port 45002 in 00:00:00.0125916
Started Port 45003 in 00:00:00.0140987
Started Port 45004 in 00:00:00.0214274
Started Port 45005 in 00:00:00.0166746
Started Port 45006 in 00:00:00.0178583
Started Port 45007 in 00:00:00.0203611
Started Port 45008 in 00:00:00.0187707
Started Port 45009 in 00:00:00.0209386
Started Port 45010 in 00:00:00.0229595
Started Port 45011 in 00:00:00.0298687
Started Port 45012 in 00:00:00.0331132
Started Port 45013 in 00:00:00.0312815
Started Port 45014 in 00:00:00.0295004
Started Port 45015 in 00:00:00.0312391
Started Port 45016 in 00:00:00.0326538
Started Port 45017 in 00:00:00.0329316
Started Port 45018 in 00:00:00.0330471
Started Port 45019 in 00:00:00.0353324
Started Port 45020 in 00:00:00.0391780
Started Port 45021 in 00:00:00.0405106
Started Port 45022 in 00:00:00.0391909
Started Port 45023 in 00:00:00.0410726
Started Port 45024 in 00:00:00.0519416
約 400 個のポートが開かれた後、各ポートが起動するまでにかかる時間を確認します。1~2秒?この操作では、CPU の使用率も非常に高くなります。
Started Port 45399 in 00:00:01.3031324
Started Port 45400 in 00:00:01.2686192
Started Port 45401 in 00:00:01.2367192
Started Port 45402 in 00:00:01.3912566
Started Port 45403 in 00:00:01.2710675
Started Port 45404 in 00:00:01.2500153
Started Port 45405 in 00:00:01.2685378
Started Port 45406 in 00:00:01.3358896
Started Port 45407 in 00:00:01.2972177
Started Port 45408 in 00:00:01.3002466
Started Port 45409 in 00:00:01.4087936
Started Port 45410 in 00:00:01.5042491
Started Port 45411 in 00:00:01.2869177
Started Port 45412 in 00:00:01.3284299
Started Port 45413 in 00:00:01.3202311
Started Port 45414 in 00:00:01.4406063
Started Port 45415 in 00:00:01.3534663
Started Port 45416 in 00:00:01.7562387
Started Port 45417 in 00:00:01.5572173
Started Port 45418 in 00:00:01.4617214
Started Port 45419 in 00:00:02.1260768
Started Port 45420 in 00:00:01.6841706
Started Port 45421 in 00:00:01.7514512
Started Port 45422 in 00:00:01.5182234
質問:
- 各ポートを開くのに最後のポートよりも時間がかかるのはなぜですか?
- CPUがどんどん高くなるのはなぜですか
- 私は何か間違ったことをしていますか?ソケットを開いて接続をリッスンするより効率的な方法はありますか?
- これは OS の問題ですか、それとも .net の問題ですか? これを Windows 7 でテストしましたが、サーバー OS でテストした場合は異なると思いますか? 2008 R2 と Win7 SP のカーネルは同じだと思うので、それが問題かどうかはわかりません。
ハードウェア:
- Win7 x64 Ultimate、8 GB RAM、I7、SSD など
これに対する解決策を見つけることは私にとって重要ではありませんが、それは素晴らしいことです。このシミュレーター アプリを起動して、妥当な時間内に 500 ~ 700 の一意の TCP ポートをリッスンしたいと考えています。より良い方法があれば教えてください...何が起こっているのか、または代替オプションに非常に興味があります。
ありがとう!
更新 1
CPU/メモリがほとんどない Raspberry Pi デバイスでテストしたところ、ほぼ瞬時に動作しました。他の人はコメントですぐに言った..そして1人は同じものを見たと言いました. 別の PC でもテストしましたが、同じ問題が発生しました。無効化されたファイアウォール、AV など。なぜこれが起こっているのか、非常に興味があります。