feat : 스트레스 테스트 기능 추가 / 패킷 처리량 제한 / 프로젝트 상황 리드미 추가
This commit is contained in:
@@ -8,8 +8,6 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Release 빌드에서 메모리 덤프 생성용 -->
|
||||
<PackageReference Include="Microsoft.Diagnostics.NETCore.Client" Version="0.2.553101" Condition="'$(Configuration)' == 'Release'" />
|
||||
<PackageReference Include="Dapper" Version="2.1.66" />
|
||||
<PackageReference Include="Dapper.Contrib" Version="2.0.78" />
|
||||
<PackageReference Include="LiteNetLib" Version="2.0.2" />
|
||||
|
||||
@@ -184,6 +184,22 @@ public abstract class ServerBase : INetEventListener
|
||||
return;
|
||||
}
|
||||
|
||||
// 패킷 레이트 리미팅 체크
|
||||
if (session.CheckRateLimit())
|
||||
{
|
||||
// 3회 연속 초과 시 강제 연결 해제
|
||||
if (session.RateLimitViolations >= 3)
|
||||
{
|
||||
Log.Warning("[Server] 레이트 리밋 초과 강제 해제 HashKey={Key} PeerId={Id}", session.HashKey, peer.Id);
|
||||
peer.Disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
Log.Warning("[Server] 레이트 리밋 초과 ({Count}회) HashKey={Key} PeerId={Id}", session.RateLimitViolations, session.HashKey,
|
||||
peer.Id);
|
||||
return; // 패킷 드롭
|
||||
}
|
||||
|
||||
HandlePacket(peer, session.HashKey, type, payload);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -22,10 +22,55 @@ public class Session
|
||||
set;
|
||||
}
|
||||
|
||||
public Session(long hashKey, NetPeer peer)
|
||||
// ─── 패킷 레이트 리미팅 ───────────────────────────
|
||||
private int packetCount;
|
||||
private long windowStartTicks;
|
||||
|
||||
/// <summary>초당 허용 패킷 수</summary>
|
||||
public int MaxPacketsPerSecond { get; set; }
|
||||
|
||||
/// <summary>연속 초과 횟수</summary>
|
||||
public int RateLimitViolations { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 패킷 수신 시 호출. 초당 제한 초과 시 true 반환.
|
||||
/// </summary>
|
||||
public bool CheckRateLimit()
|
||||
{
|
||||
long now = Environment.TickCount64;
|
||||
|
||||
// 1초(1000ms) 윈도우 초과 시 리셋
|
||||
if (now - windowStartTicks >= 1000)
|
||||
{
|
||||
windowStartTicks = now;
|
||||
packetCount = 0;
|
||||
}
|
||||
|
||||
packetCount++;
|
||||
|
||||
if (packetCount > MaxPacketsPerSecond)
|
||||
{
|
||||
RateLimitViolations++;
|
||||
return true; // 제한 초과
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>위반 카운트 초기화</summary>
|
||||
public void ResetViolations()
|
||||
{
|
||||
RateLimitViolations = 0;
|
||||
}
|
||||
|
||||
public Session(long hashKey, NetPeer peer, int maxPacketsPerSecond = 60)
|
||||
{
|
||||
HashKey = hashKey;
|
||||
Peer = peer;
|
||||
Token = null;
|
||||
MaxPacketsPerSecond = maxPacketsPerSecond;
|
||||
packetCount = 0;
|
||||
windowStartTicks = Environment.TickCount64;
|
||||
RateLimitViolations = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,6 @@ using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Serilog;
|
||||
|
||||
#if !DEBUG
|
||||
using Microsoft.Diagnostics.NETCore.Client;
|
||||
#endif
|
||||
|
||||
namespace ServerLib.Utils;
|
||||
|
||||
/// <summary>
|
||||
@@ -163,10 +159,38 @@ public static class CrashDumpHandler
|
||||
}
|
||||
|
||||
#if !DEBUG
|
||||
// Windows MiniDumpWriteDump P/Invoke
|
||||
[DllImport("dbghelp.dll", SetLastError = true)]
|
||||
private static extern bool MiniDumpWriteDump(
|
||||
IntPtr hProcess, uint processId, IntPtr hFile,
|
||||
uint dumpType, IntPtr exceptionParam,
|
||||
IntPtr userStreamParam, IntPtr callbackParam);
|
||||
|
||||
private const uint MiniDumpWithFullMemory = 0x00000002;
|
||||
|
||||
private static void WriteDumpFile(string path)
|
||||
{
|
||||
DiagnosticsClient client = new DiagnosticsClient(Environment.ProcessId);
|
||||
client.WriteDump(DumpType.WithHeap, path, logDumpGeneration: false);
|
||||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
Log.Warning("[CrashDump] 덤프 생성은 Windows만 지원");
|
||||
return;
|
||||
}
|
||||
|
||||
using Process process = Process.GetCurrentProcess();
|
||||
using FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
|
||||
bool success = MiniDumpWriteDump(
|
||||
process.Handle,
|
||||
(uint)process.Id,
|
||||
fs.SafeFileHandle.DangerousGetHandle(),
|
||||
MiniDumpWithFullMemory,
|
||||
IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
int err = Marshal.GetLastWin32Error();
|
||||
Log.Error("[CrashDump] MiniDumpWriteDump 실패 (Win32 Error={Err})", err);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user