로컬간 통신에서 HTTPS 유지와 Keep-Alive로 프록시 최적화

2026-03-30#https#keep-alive#proxy#nodejs#performance

Overview

hop: 요청이 목적지까지 가는 중간 단계 하나를 뜻한다.
https.Agent: Node.js 에서 HTTPS 연결을 관리하고 재사용하는 객체이다.
Keep-Alive: 한 번 만든 연결을 바로 끊지 않고 재사용해서 연결 생성 비용을 줄이는 방식이다.


문제 상황

현재 환경은 아래와 같았다.

초기 구조에서는 아래 흐름으로 동작했다.

  1. 브라우저가 https://...:9443/subapi/* 호출

  2. 9443 서버가 내부적으로 https://127.0.0.1:7443/api/* 로 프록시

  3. 응답을 다시 브라우저로 전달

로컬 PC 에서 통신하는 것이라서 빠를 것 같았지만, 내부적으로는 HTTPS 프록시 hop 이 한 번 더 있었기 때문에 TLS 핸드셰이크와 연결 생성 비용이 반복될 수 있는 구조였다.

특히 새로고침 직후 여러 API 를 연속 호출하거나, 탭 전환 시 요청이 짧은 시간 안에 몰리는 화면에서 속도 저하가 더 체감됐다.


속도 저하 원인

핵심 원인은 아래와 같았다.

즉, 문제는 "같은 PC 의 localhost 이므로 프록시 비용이 거의 없을 것"이라는 기대와 달리, 매 요청마다 TLS 핸드셰이크가 동작한다는 점이었다.

Keep-Alive 를 쓰지 않으면 요청마다 TCP 연결과 TLS 세션 협상이 반복될 수 있고, 이 비용은 한 번의 호출에서는 작아 보여도 연속 호출이 많아지면 누적 체감이 커질 수 있다.


로컬 통신인데 HTTP 로 전환하지 않은 이유

가장 먼저 떠올린 대안은 내부 서버만 HTTP 로 낮추는 방법이다. 같은 PC 안에서만 통신하므로 성능상 유리해 보였다.

이 구조를 단순화하면 아래처럼 볼 수 있다.

하지만, 이번 환경에서는 내부 hop 도 TLS 를 유지해야 한다는 보안 조건이 있었기 때문에, 이 방향은 맞지 않았다.

특히 이전에 정리했던 것처럼 본문 암호화가 있다고 해서 전송 계층 보안이 대체되는 것은 아니다.
즉, 내부 hop 을 HTTP + AES 로 두는 방향보다, 내부 hop 도 HTTPS 를 유지한 채 연결 재사용으로 비용을 줄이는 쪽이 더 일관된 선택이었다.

선택한 방향은 아래와 같았다.


해결 방법

적용한 방법이다.

  1. 내부 업스트림 연결을 계속 HTTPS 로 유지

  2. http-proxyhttps.Agent 를 연결

  3. keepAlive: true 로 업스트림 연결을 재사용

  4. 요청마다 TLS 연결을 새로 맺지 않도록 프록시를 최적화

이 방식의 장점은 아래와 같았다.


적용 코드 예시

실제 적용은 https.Agent 를 프록시의 업스트림 agent 로 연결하는 방식이었다.

import * as https from "https";
import { createProxyServer } from "http-proxy";
 
const proxyHttpsAgent = new https.Agent({
  keepAlive: true,  // 연결을 재사용하게 해서 요청마다 소켓을 새로 만들지 않도록 돕는다.
  keepAliveMsecs: 30_000,  // 유휴 연결을 얼마나 유지할지에 영향을 준다.
  maxSockets: 50,  // 동시에 유지할 연결 수를 제어한다.
  maxFreeSockets: 10,  // 동시에 유지할 연결 수를 제어한다.
  rejectUnauthorized: false,  // 개발 환경에 맞게 조정
});
 
const subProxy = createProxyServer({
  target: `https://127.0.0.1:${SUB_HTTPS_PORT}`,
  changeOrigin: false,
  ws: true,
  xfwd: true,
  agent: proxyHttpsAgent,
  secure: false,  // 개발 환경에 맞게 조정
});

핵심은 agent: proxyHttpsAgent 이다. 이 설정으로 프록시가 업스트림 HTTPS 연결을 재사용할 수 있게 된다.


속도 비교 결과

브러우저에 요청 시간을 콘솔로 출력했다.

[API TIMING] [subserver] GET https://localhost:9443/subapi/users total=82.4ms
[HTTPS 9443][SUB API] GET /subapi/users -> 200 64ms
Image Image

결론

같은 PC 안에서 두 서버가 실행되더라도, 내부 HTTPS 프록시 hop 은 성능 병목이 될 수 있다.

하지만 내부 hop 을 HTTP 로 내리지 않고, HTTPS 유지 + Keep-Alive 조합만으로 TLS 비용을 줄이고 구조 안정성을 유지할 수 있었다.

보안 요구사항 때문에 내부 HTTP 전환이 어려워, 내부 HTTPS 는 유지하고 업스트림 연결 재사용을 적용했다.

구조를 크게 바꾸지 않으면서도 가장 부담이 적은 최적화였다.


느낀 점


참고 링크