feat : 스트레스 테스트 기능 추가 / 패킷 처리량 제한 / 프로젝트 상황 리드미 추가
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
using ClientTester.DummyService;
|
||||
using ClientTester.EchoDummyService;
|
||||
using ClientTester.StressTest;
|
||||
using ClientTester.Utils;
|
||||
using Serilog;
|
||||
|
||||
class EcoClientTester
|
||||
{
|
||||
public static readonly string SERVER_IP = "localhost";
|
||||
public static readonly int SERVER_PORT = 9500;
|
||||
public static string SERVER_IP = "localhost";
|
||||
public static int SERVER_PORT = 9500;
|
||||
public static readonly string CONNECTION_KEY = "test";
|
||||
public static readonly int CLIENT_COUNT = 10;
|
||||
public static int CLIENT_COUNT = 100;
|
||||
|
||||
private async Task StartEchoDummyTest()
|
||||
{
|
||||
@@ -78,8 +79,78 @@ class EcoClientTester
|
||||
}
|
||||
}
|
||||
|
||||
private async Task StartStressTest(int duration, int sendInterval, int rampInterval, int clientsPerRamp)
|
||||
{
|
||||
try
|
||||
{
|
||||
CancellationTokenSource cts = new CancellationTokenSource();
|
||||
Console.CancelKeyPress += (_, e) =>
|
||||
{
|
||||
e.Cancel = true;
|
||||
Log.Warning("[SHUTDOWN] Ctrl+C 감지, 종료 중...");
|
||||
cts.Cancel();
|
||||
};
|
||||
|
||||
StressTestService service = new StressTestService(
|
||||
CLIENT_COUNT, SERVER_IP, SERVER_PORT, CONNECTION_KEY,
|
||||
durationSec: duration,
|
||||
sendIntervalMs: sendInterval,
|
||||
rampUpIntervalMs: rampInterval,
|
||||
clientsPerRamp: clientsPerRamp);
|
||||
|
||||
service.OnTestCompleted += () =>
|
||||
{
|
||||
Log.Information("[STRESS] 테스트 시간 종료.");
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
await service.RunAsync(cts.Token);
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
|
||||
service.PrintFinalReport();
|
||||
|
||||
string timestamp = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
|
||||
string csvPath = $"results/stress_{CLIENT_COUNT}clients_{timestamp}.csv";
|
||||
Directory.CreateDirectory("results");
|
||||
service.ExportCsv(csvPath);
|
||||
|
||||
service.Stop();
|
||||
await Log.CloseAndFlushAsync();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"[SHUTDOWN] 예외 발생 : {e}");
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintUsage()
|
||||
{
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("사용법:");
|
||||
Console.WriteLine(" EchoClientTester 대화형 모드");
|
||||
Console.WriteLine(" EchoClientTester stress [옵션] 스트레스 테스트");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("스트레스 테스트 옵션:");
|
||||
Console.WriteLine(" -c, --clients <수> 클라이언트 수 (기본: 50)");
|
||||
Console.WriteLine(" -d, --duration <초> 테스트 시간 (기본: 60, 0=무제한)");
|
||||
Console.WriteLine(" -i, --interval <ms> 전송 주기 (기본: 100)");
|
||||
Console.WriteLine(" -r, --ramp <ms> Ramp-up 간격 (기본: 1000)");
|
||||
Console.WriteLine(" -b, --batch <수> Ramp-up 당 클라이언트 수 (기본: 10)");
|
||||
Console.WriteLine(" --ip <주소> 서버 IP (기본: localhost)");
|
||||
Console.WriteLine(" --port <포트> 서버 포트 (기본: 9500)");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("예시:");
|
||||
Console.WriteLine(" EchoClientTester stress -c 100 -d 120");
|
||||
Console.WriteLine(" EchoClientTester stress -c 200 -d 60 -r 500 -b 20 --ip 192.168.0.10");
|
||||
}
|
||||
|
||||
private static async Task Main(string[] args)
|
||||
{
|
||||
// 유니코드 문자(═, ║ 등) 콘솔 깨짐 방지
|
||||
Console.OutputEncoding = System.Text.Encoding.UTF8;
|
||||
|
||||
// 크래시 덤프 핸들러 (Release: .log + .dmp / Debug: .log)
|
||||
CrashDumpHandler.Register();
|
||||
|
||||
@@ -92,29 +163,95 @@ class EcoClientTester
|
||||
.WriteTo.File($"logs2/log_{timestamp}.txt")
|
||||
.CreateLogger();
|
||||
|
||||
Log.Information("========== 더미 클라 테스터 ==========");
|
||||
Log.Information("1. 에코 서버");
|
||||
Log.Information("2. 더미 클라(이동만)");
|
||||
Log.Information("====================================");
|
||||
Log.Information("1 / 2 : ");
|
||||
EcoClientTester tester = new EcoClientTester();
|
||||
|
||||
string? input = Console.ReadLine();
|
||||
if (!int.TryParse(input, out int choice) || (choice != 1 && choice != 2))
|
||||
// CLI 모드: stress 명령
|
||||
if (args.Length > 0 && args[0].Equals("stress", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Log.Warning("1 또는 2만 입력하세요.");
|
||||
// 기본값
|
||||
CLIENT_COUNT = 50;
|
||||
int duration = 60;
|
||||
int sendInterval = 100;
|
||||
int rampInterval = 1000;
|
||||
int clientsPerRamp = 10;
|
||||
|
||||
for (int i = 1; i < args.Length; i++)
|
||||
{
|
||||
switch (args[i])
|
||||
{
|
||||
case "-c": case "--clients":
|
||||
if (i + 1 < args.Length) CLIENT_COUNT = int.Parse(args[++i]);
|
||||
break;
|
||||
case "-d": case "--duration":
|
||||
if (i + 1 < args.Length) duration = int.Parse(args[++i]);
|
||||
break;
|
||||
case "-i": case "--interval":
|
||||
if (i + 1 < args.Length) sendInterval = int.Parse(args[++i]);
|
||||
break;
|
||||
case "-r": case "--ramp":
|
||||
if (i + 1 < args.Length) rampInterval = int.Parse(args[++i]);
|
||||
break;
|
||||
case "-b": case "--batch":
|
||||
if (i + 1 < args.Length) clientsPerRamp = int.Parse(args[++i]);
|
||||
break;
|
||||
case "--ip":
|
||||
if (i + 1 < args.Length) SERVER_IP = args[++i];
|
||||
break;
|
||||
case "--port":
|
||||
if (i + 1 < args.Length) SERVER_PORT = int.Parse(args[++i]);
|
||||
break;
|
||||
case "-h": case "--help":
|
||||
PrintUsage();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await tester.StartStressTest(duration, sendInterval, rampInterval, clientsPerRamp);
|
||||
return;
|
||||
}
|
||||
|
||||
// CLI 모드: help
|
||||
if (args.Length > 0 && (args[0] == "-h" || args[0] == "--help"))
|
||||
{
|
||||
PrintUsage();
|
||||
return;
|
||||
}
|
||||
|
||||
// 대화형 모드 (기존)
|
||||
Log.Information("========== 더미 클라 테스터 ==========");
|
||||
Log.Information("1. 에코 서버");
|
||||
Log.Information("2. 더미 클라(이동만)");
|
||||
Log.Information("3. 스트레스 테스트 (부하)");
|
||||
Log.Information("====================================");
|
||||
Log.Information("1 / 2 / 3 : ");
|
||||
|
||||
string? input = Console.ReadLine();
|
||||
if (!int.TryParse(input, out int choice) || choice < 1 || choice > 3)
|
||||
{
|
||||
Log.Warning("1, 2, 3 중 입력하세요.");
|
||||
return;
|
||||
}
|
||||
|
||||
EcoClientTester tester = new EcoClientTester();
|
||||
if (choice == 1)
|
||||
{
|
||||
// 에코 서버 실행
|
||||
await tester.StartEchoDummyTest();
|
||||
}
|
||||
else if (choice == 2)
|
||||
{
|
||||
// 더미 클라 실행
|
||||
await tester.StartDummyTest();
|
||||
}
|
||||
else if (choice == 3)
|
||||
{
|
||||
// 대화형 스트레스 테스트 설정
|
||||
Log.Information("클라이언트 수 (기본 50): ");
|
||||
string? countInput = Console.ReadLine();
|
||||
CLIENT_COUNT = string.IsNullOrEmpty(countInput) ? 50 : int.Parse(countInput);
|
||||
|
||||
Log.Information("테스트 시간(초) (기본 60, 0=무제한): ");
|
||||
string? durInput = Console.ReadLine();
|
||||
int dur = string.IsNullOrEmpty(durInput) ? 60 : int.Parse(durInput);
|
||||
|
||||
await tester.StartStressTest(dur, 100, 1000, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user