HTTP.SYS 고성능 튜닝

· 기능

sgcWebSockets 2026.5.0부터 TsgcWSServer_HTTPAPI 컴포넌트가 TsgcServerHTTPAPI_FineTune 타입의 새 published 속성인 FineTune을 노출해요. Windows HTTP Server API(http.sys)가 요청을 큐잉, 디스패치, 완료 처리하는 방식에 영향을 미치는 모든 저수준 커널 모드 설정을 그룹화한 속성이에요. 지금까지 이런 설정들은 컴포넌트에 존재하지 않거나 하드코딩되어 있었지만 — 이제 published 속성으로 노출되며, 폼과 함께 저장되고, 디자인 타임에 조정할 수 있어요.

FineTune 속성은 4개의 하위 속성을 가진 TPersistent 컨테이너예요: QueueLength, SkipIOCPOnSuccess, OperatingMode, HighPerfAcceptsPerWorker. 모든 속성의 기본값은 기존 동작을 유지하도록 설정되어 있어서, 2026.5.0으로 업그레이드해도 코드 변경이 필요 없어요. 특정 워크로드가 요구할 때 각 조정을 개별적으로 선택해서 적용할 수 있어요.

FineTune 속성

QueueLength : ULONG (기본값 1000)

역할. HttpServerQueueLengthProperty 커널 설정을 감싸요. 서버가 요청을 디큐하기 전에 http.sys가 커널 모드 큐에 보관할 수 있는 대기 요청의 수를 제어해요. 큐가 가득 차면 커널은 사용자 모드까지 도달하지 않고 새 연결에 직접 503 Service Unavailable로 응답해요.

개선점. 버스트성 워크로드(네트워크 문제 후 재연결하는 수천 개의 IoT 기기, 플릿 롤아웃, 장 시작 트래픽 급증 등)에서 QueueLength를 늘리면 프로세스가 보기 전에 커널이 클라이언트를 거부하는 것을 방지해서 연쇄적인 클라이언트 재시도를 피할 수 있어요. 기본값 1000은 Windows 커널 기본값과 일치하며 최신 워크로드에서는 보수적인 값이에요. 유효 범위는 최대 65535예요.

SkipIOCPOnSuccess : Boolean (기본값 False)

역할. True로 설정하면 SetFileCompletionNotificationModes를 통해 요청 큐 핸들에 FILE_SKIP_COMPLETION_PORT_ON_SUCCESSFILE_SKIP_SET_EVENT_ON_HANDLE 플래그를 활성화해요. 그러면 커널은 오버랩 I/O 작업이 동기적으로 완료될 때 IOCP에 완료 패킷을 보내는 것을 건너뛰어요.

개선점. 호출이 동기적으로 NO_ERROR를 반환할 때 핫 요청 경로에서 커널-사용자 모드 전환을 제거해요 — 워커는 IOCP 패킷을 기다리지 않고 호출 스레드에서 인라인으로 완료를 디스패치해요. 이는 Microsoft의 레퍼런스 "HTTP Server High Performance" 샘플이 사용하는 패턴이에요. 기본값 False는 의도적이에요. 플래그를 활성화하려면 호출자 측에서 인라인 완료를 처리해야 해요. 이 속성은 처리량 향상이 추가 코드 경로를 정당화하는 워크로드에서 OperatingMode = ompHighPerf와 함께 사용하도록 설계되었어요.

OperatingMode : TsgcHTTPAPIOperatingMode (기본값 ompClassic)

역할. 두 가지 수락/디스패치 아키텍처 중 하나를 선택해요:

개선점. ompHighPerf는 서버가 깊은 단일 스트림 파이프라인(대용량 프레임 업/다운로드)이나 많은 동시 클라이언트(수백~수천)를 처리할 때 효과가 있어요. 사전 게시된 수신 윈도우가 연결당 할당 없이 버스트를 흡수하고, 인라인 디스패치가 수락자 핸드오프 병목을 제거해요. 트래픽이 적은 API와 개발 환경에서는 기본값 ompClassic을 유지하세요 — 가벼운 워크로드에서는 128개의 사전 게시 컨텍스트를 유지하는 오버헤드가 절감되는 비용보다 더 커요. 모드는 생성 시에만 변경할 수 있어요. 단일 프로세스 수명 내에서 모드 혼용은 지원되지 않아요.

HighPerfAcceptsPerWorker : Integer (기본값 4)

역할. OperatingMode = ompHighPerf일 때 각 IOCP 워커가 사전 게시하는 비동기 수신의 개수를 제어해요. ompClassic 모드에서는 이 값이 무시돼요. 서버가 유지하는 동시 미처리 수신의 총 개수는 ThreadPoolSize × HighPerfAcceptsPerWorker와 같아요.

개선점. 워커당 윈도우가 깊을수록 서버가 핫 경로에서 새 컨텍스트를 할당하지 않고도 더 큰 들어오는 요청 버스트를 흡수할 수 있어요. 고동시성 배포(IoT 플릿, 시장 데이터 분배, 팬아웃 브로커)에서는 이 값을 올리세요. 트레이드오프는 메모리예요 — 각 사전 게시된 수신은 완료될 때까지 요청 버퍼(~16KB)를 예약해요. 기본값 4는 MSDN "HP" 샘플에 대해 검증된 보수적인 중간값이에요.

사용 예제

다음 스니펫은 고동시성 IoT 백엔드를 위해 HTTP.sys 서버를 설정해요. 재연결 폭주를 흡수하기 위한 큰 커널 큐, 확장된 사전 게시 수신 윈도우를 가진 HighPerf 디스패치, 그리고 인라인 완료 디스패치를 활성화했어요.

uses
  sgcWebSocket_Server_HTTPAPI,
  sgcWebSocket_HTTPAPI_Server;   // TsgcHTTPAPIOperatingMode
var
  oServer: TsgcWSServer_HTTPAPI;
begin
  oServer := TsgcWSServer_HTTPAPI.Create(nil);
  oServer.Host := '0.0.0.0';
  oServer.Port := 8080;
  // absorb 10,000-device reconnect bursts before kernel-level 503
  oServer.FineTune.QueueLength := 10000;
  // switch from single-acceptor to pre-posted IOCP workers
  oServer.FineTune.OperatingMode := ompHighPerf;
  // widen the per-worker pre-posted receive window (32 threads * 8 = 256)
  oServer.FineTune.HighPerfAcceptsPerWorker := 8;
  // dispatch inline on sync-success completions; skip the IOCP round-trip
  oServer.FineTune.SkipIOCPOnSuccess := True;
  oServer.Active := True;
end;

일반적인 내부 또는 트래픽이 적은 API의 경우, 모든 FineTune 속성을 기본값으로 두세요:

oServer := TsgcWSServer_HTTPAPI.Create(nil);
oServer.Host := 'localhost';
oServer.Port := 8080;
// FineTune defaults: QueueLength=1000, SkipIOCPOnSuccess=False,
// OperatingMode=ompClassic, HighPerfAcceptsPerWorker=4
oServer.Active := True;