빠른 설정
import { Agent, request } from "node:https";
const agent = new Agent({
keepAlive: true,
maxSockets: 50,
maxFreeSockets: 10,
timeout: 30_000,
});
const req = request("https://api.example.com/users", { agent }, (res) => {
res.resume();
});
req.end();| 목적 | 먼저 볼 옵션 |
|---|---|
| 같은 origin 연결 재사용 | keepAlive: true |
| 동시 연결 상한 | maxSockets |
| 유휴 socket 보관 수 | maxFreeSockets |
| 오래 열린 socket 정리 | timeout |
| 요청별 agent 비활성화 | agent: false |
Agent 역할
HTTP Agent는 client 요청에서 socket을 만들고 재사용하는 관리자입니다. http.request()나 https.request()가 매번 새 TCP/TLS 연결을 만들면 handshake 비용이 커지므로, 같은 origin으로 반복 요청하는 코드에서는 Agent 설정이 성능과 안정성에 직접 영향을 줍니다.
const agent = new https.Agent({ keepAlive: true });
https.get("https://api.example.com/health", { agent }, (res) => {
res.resume();
});keepAlive는 응답 뒤 socket을 바로 닫지 않고 재사용 후보로 보관합니다. 서버의 keep-alive timeout, 프록시, 로드밸런서 정책과 맞지 않으면 재사용하려던 socket이 이미 끊겨 오류가 날 수 있으므로 timeout과 retry 정책을 같이 봐야 합니다.
연결 수 기준
maxSockets는 origin별 동시에 열 수 있는 socket 수를 제한합니다. 너무 낮으면 요청이 agent queue에서 대기하고, 너무 높으면 상대 서버나 프록시, 로컬 파일 디스크립터 한계를 압박할 수 있습니다.
const agent = new https.Agent({
keepAlive: true,
maxSockets: 100,
maxFreeSockets: 20,
});maxFreeSockets는 유휴 상태로 보관할 socket 수입니다. 트래픽이 burst 형태라면 어느 정도 보관이 도움이 되지만, 대상 origin이 많거나 프로세스 수가 많으면 유휴 socket도 누적 비용이 됩니다.
언제 설정할까
외부 API, 내부 microservice, object storage처럼 같은 host로 반복 호출하는 서버 프로세스라면 Agent를 명시하는 편이 좋습니다. 짧은 CLI에서 요청 한두 번만 보내는 경우에는 기본값으로 충분한 경우가 많습니다.
export const apiAgent = new https.Agent({
keepAlive: true,
maxSockets: Number(process.env.API_MAX_SOCKETS ?? 50),
});라이브러리 경계에서는 Agent를 옵션으로 주입받게 만드는 편이 안전합니다. 호출자가 서버 환경, CLI 환경, 테스트 환경에 맞춰 연결 정책을 고를 수 있기 때문입니다.
export function createClient({ agent } = {}) {
return {
get(path) {
return requestJson(baseUrl + path, { agent });
},
};
}주의할 점
client Agent의 keepAlive와 server의 keepAliveTimeout은 다른 설정입니다. 서버 종료 지연을 줄이는 설정과
클라이언트 연결 재사용 설정을 같은 문제로 다루면 장애 원인 분석이 흐려집니다.
연결 재사용은 실패 재시도와 함께 설계해야 합니다. 유휴 socket이 서버 쪽에서 먼저 닫힌 뒤 재사용되면 ECONNRESET 같은 오류가 날 수 있습니다. idempotent 요청인지, 재시도 가능한 오류인지, 요청 body를 다시 보낼 수 있는지까지 같이 정해야 합니다.
참고 링크
2 sources