Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -159,20 +159,6 @@ secrets.json
*.temp
~$*

# Media files
*.wav
*.mp3
*.mp4
*.avi
*.wmv
*.flv
*.mkv
*.webm
*.m4a
*.m4v
*.m4b
*.m4r
*.m4p

# Data files
*.csv
Expand Down
9 changes: 9 additions & 0 deletions ProjectVG.Api/ApiServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,5 +75,14 @@ public static IServiceCollection AddDevelopmentCors(this IServiceCollection serv

return services;
}

/// <summary>
/// 부하테스트 전용 성능 모니터링 서비스
/// </summary>
public static IServiceCollection AddLoadTestPerformanceServices(this IServiceCollection services)
{
services.AddSingleton<PerformanceCounterService>();
return services;
}
Comment on lines +82 to +86
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

CPU 사용률 계산 로직 오류 가능성(하위 서비스) — 잘못된 퍼센트 산출

현재 PerformanceCounterService.GetCpuUsage()가 누적 CPU 시간(TotalProcessorTime ms)을 “퍼센트”처럼 반환하고 있어 경고/모니터링이 왜곡됩니다. 샘플링 기반으로 벽시계 시간 대비 CPU 시간 Δ를 계산하도록 수정 필요.

예시(다른 파일에 적용 필요):

// PerformanceCounterService.cs 일부
private TimeSpan _prevCpu = TimeSpan.Zero;
private DateTime _prevTs = DateTime.UtcNow;

private double GetCpuUsage()
{
    try
    {
        var nowCpu = _currentProcess.TotalProcessorTime;
        var nowTs  = DateTime.UtcNow;

        var cpuDeltaMs = (nowCpu - _prevCpu).TotalMilliseconds;
        var wallMs     = (nowTs - _prevTs).TotalMilliseconds;

        _prevCpu = nowCpu;
        _prevTs  = nowTs;

        if (wallMs <= 0) return 0;

        // 논리 코어 수 고려
        var pct = (cpuDeltaMs / (wallMs * Environment.ProcessorCount)) * 100.0;
        return Math.Clamp(pct, 0, 100);
    }
    catch { return 0; }
}

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Searching repository for PerformanceCounterService / GetCpuUsage / TotalProcessorTime..."
rg -n --hidden --no-ignore-vcs -S '\bPerformanceCounterService\b' || true
rg -n --hidden --no-ignore-vcs -S '\bGetCpuUsage\b' || true
rg -n --hidden --no-ignore-vcs -S '\bTotalProcessorTime\b' || true

echo
echo "Showing matches with context (up to 5 files)..."
rg -n -C3 --hidden --no-ignore-vcs -S 'PerformanceCounterService|GetCpuUsage|TotalProcessorTime' | sed -n '1,500p' || true

Length of output: 9537


GetCpuUsage가 누적 CPU 시간(ms)을 반환 — 실제 퍼센트(%) 계산으로 수정 필요

위치: ProjectVG.Api/Services/PerformanceCounterService.cs (GetCpuUsage). 현재 GetCpuUsage()가 _currentProcess.TotalProcessorTime.TotalMilliseconds를 반환해 CpuUsagePercent에 누적 밀리초가 들어갑니다. 타이머(5s) 샘플링 기준으로 이전 TotalProcessorTime/타임스탬프와의 Δ를 이용해 벽시계 시간 대비 CPU 시간 비율을 계산하도록 변경하세요.

권장 수정 예시:

private TimeSpan _prevCpu = TimeSpan.Zero;
private DateTime _prevTs = DateTime.UtcNow;

private double GetCpuUsage()
{
    try
    {
        var nowCpu = _currentProcess.TotalProcessorTime;
        var nowTs  = DateTime.UtcNow;

        var cpuDeltaMs = (nowCpu - _prevCpu).TotalMilliseconds;
        var wallMs     = (nowTs  - _prevTs).TotalMilliseconds;

        _prevCpu = nowCpu;
        _prevTs  = nowTs;

        if (wallMs <= 0) return 0;

        var pct = (cpuDeltaMs / (wallMs * Environment.ProcessorCount)) * 100.0;
        return Math.Clamp(pct, 0, 100);
    }
    catch { return 0; }
}

}
}
55 changes: 55 additions & 0 deletions ProjectVG.Api/Configuration/LoadTestConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using Microsoft.AspNetCore.Server.Kestrel.Core;

namespace ProjectVG.Api.Configuration;

/// <summary>
/// 부하테스트 환경을 위한 성능 최적화 설정을 제공합니다.
/// </summary>
public static class LoadTestConfiguration
{
/// <summary>
/// 부하테스트 환경에서 Kestrel 서버의 성능을 최적화합니다.
/// </summary>
/// <param name="options">Kestrel 서버 옵션</param>
public static void ConfigureKestrelForLoadTest(KestrelServerOptions options)
{
// 연결 한도 설정 (부하테스트용 고성능)
options.Limits.MaxConcurrentConnections = 1000;
options.Limits.MaxConcurrentUpgradedConnections = 1000;

// 요청 크기 및 타임아웃 최적화
options.Limits.MaxRequestBodySize = 10_000_000; // 10MB
options.Limits.RequestHeadersTimeout = TimeSpan.FromSeconds(30);
options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2);
options.Limits.RequestHeadersTimeout = TimeSpan.FromSeconds(10);

Comment on lines +21 to +25
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

RequestHeadersTimeout 이중 설정 제거

동일 옵션을 30s → 10s로 두 번 설정하고 있습니다. 하나로 정리하세요.

-        options.Limits.RequestHeadersTimeout = TimeSpan.FromSeconds(30);
         options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2);
         options.Limits.RequestHeadersTimeout = TimeSpan.FromSeconds(10);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
options.Limits.MaxRequestBodySize = 10_000_000; // 10MB
options.Limits.RequestHeadersTimeout = TimeSpan.FromSeconds(30);
options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2);
options.Limits.RequestHeadersTimeout = TimeSpan.FromSeconds(10);
options.Limits.MaxRequestBodySize = 10_000_000; // 10MB
options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2);
options.Limits.RequestHeadersTimeout = TimeSpan.FromSeconds(10);
🤖 Prompt for AI Agents
In ProjectVG.Api/Configuration/LoadTestConfiguration.cs around lines 21 to 25,
the RequestHeadersTimeout is set twice (first to 30s, then to 10s); remove the
duplicate by keeping a single options.Limits.RequestHeadersTimeout assignment
with the intended value (10 seconds) and delete the earlier 30-second line so
the configuration is unambiguous.

// HTTP/2 최적화
options.Limits.Http2.MaxStreamsPerConnection = 100;
options.Limits.Http2.HeaderTableSize = 4096;
options.Limits.Http2.MaxFrameSize = 16384;

// 성능 로깅
Console.WriteLine($"LoadTest Kestrel Configuration Applied:");
Console.WriteLine($"- MaxConcurrentConnections: {options.Limits.MaxConcurrentConnections}");
Console.WriteLine($"- MaxRequestBodySize: {options.Limits.MaxRequestBodySize} bytes");
}

/// <summary>
/// 부하테스트 환경에서 ThreadPool을 최적화합니다.
/// </summary>
public static void ConfigureThreadPoolForLoadTest()
{
// ThreadPool 최소 스레드 수 설정 (부하테스트용)
ThreadPool.SetMinThreads(100, 100);

// ThreadPool 상태 로깅
ThreadPool.GetMinThreads(out int minWorkerThreads, out int minCompletionPortThreads);
ThreadPool.GetMaxThreads(out int maxWorkerThreads, out int maxCompletionPortThreads);

Console.WriteLine($"ThreadPool Configuration:");
Console.WriteLine($"- Min Worker Threads: {minWorkerThreads}");
Console.WriteLine($"- Min Completion Port Threads: {minCompletionPortThreads}");
Console.WriteLine($"- Max Worker Threads: {maxWorkerThreads}");
Console.WriteLine($"- Max Completion Port Threads: {maxCompletionPortThreads}");
}
}
Loading
Loading