웹 서버·WAS 용어 사전
nginx업스트림 · least_conn · max_fails · keepalive

upstream

뒤로 보낼 서버 묶음. 분배 방식과 실패 판정, 연결 재사용을 여기서 정한다.

뒤로 보낼 서버 묶음. 분배·실패 판정·연결 재사용을 여기서 정한다.

upstream backend {
    least_conn;

    server 10.0.1.10:8080 max_fails=3 fail_timeout=10s;
    server 10.0.1.11:8080 max_fails=3 fail_timeout=10s;
    server 10.0.1.12:8080 backup;      # 위가 다 죽으면 쓴다

    keepalive 32;
}

분배 방식

  • (기본) — 라운드로빈
  • least_conn — 활성 연결이 가장 적은 곳으로
    • 요청 처리 시간이 들쭉날쭉할 때 유리하다
    • (라운드로빈은 느린 요청이 몰린 서버에도 계속 보낸다)
  • ip_hash — 클라이언트 IP 해시 — 같은 사용자를 같은 서버로
    • 세션이 서버에 있을 때 쓴다. 다만 서버가 늘거나 줄면
    • 해시가 재배치돼 상당수가 다른 서버로 옮겨간다
  • hash $key — 임의 키 기준. consistent 를 붙이면 재배치 폭이 준다
  • weight=N — 서버 성능이 다를 때 비중을 준다

실패 판정

max_fails=3 fail_timeout=10s

  • 10초 안에 3번 실패하면, 그 10초 동안 이 서버를 뺀다

오픈소스판에는 '능동' 헬스체크가 없다

  • 주기적으로 찔러 보는 기능은 상용판(NGINX Plus)이다
  • 오픈소스는 '실제 요청이 실패하는 것' 을 보고 판단한다
  • 즉 죽은 서버로 가는 요청 몇 건은 실제로 실패한다

앞에 클라우드 LB 가 있다면 그쪽 헬스체크와 역할이 겹친다 어느 계층이 판정하는지를 정해 두지 않으면 제외·복구가 엇갈린다

keepalive 는 세 줄이 세트다

upstream backend {
    server 10.0.1.10:8080;
    keepalive 32;                    # 워커당 유지할 유휴 연결 수
}

location /api/ {
    proxy_pass http://backend;
    proxy_http_version 1.1;          # ← keepalive 는 1.1 이 필요하다
    proxy_set_header Connection "";  # ← 기본 'close' 를 지운다
}

아래 두 줄을 빠뜨리면 nginx 는 요청마다 새 TCP 연결을 만든다

  • 매번 3-way 핸드셰이크
  • 업스트림에 TIME_WAIT 소켓이 쌓인다
  • 트래픽이 오르면 포트 고갈로 이어진다 (에페메랄 포트는 약 2.8만 개)

keepalive 만 쓰고 나머지를 빠뜨리는 것이 가장 흔한 미완성 설정이다 확인: ss -s 로 TIME_WAIT 수가 비정상적으로 크면 의심

keepalive 값은 어떻게 잡나

keepalive 는 '워커당' 유지할 유휴 연결 수다

  • 실제 유휴 연결 ≈ worker_processes × keepalive

  • 너무 작으면 — 연결을 자주 새로 만든다 (의미가 반감)

  • 너무 크면 — 백엔드가 유휴 연결을 잔뜩 들고 있게 된다

    • 백엔드의 maxConnections 를 잠식한다

백엔드 수용량과 함께 정한다 — 앞단만 보고 키우면 뒤가 마른다

커넥션 수는 앞뒤를 함께 계산한다

nginx 워커 4개 · upstream keepalive 32

  • 유휴 연결 최대 4 × 32 = 128

백엔드가 3대면 각각 약 43개의 유휴 연결을 받는다 백엔드 maxConnections 가 8192 라면 여유롭지만, nginx 를 20대로 늘리면 4 × 32 × 20 = 2,560 이 된다

  • 앞단을 늘리면 뒤의 연결 수가 곱으로 늘어난다
  • 스케일아웃 계획에 이 곱셈을 반드시 넣는다

재시도가 부하를 증폭한다

proxy_next_upstream 이 켜져 있으면 실패 시 다음 서버로 넘긴다

백엔드가 전반적으로 아플 때 요청 1건 → 서버 A 실패 → B 실패 → C 실패 = 실제 부하 3배

proxy_next_upstream_tries 2;# 시도 횟수 제한
proxy_next_upstream_timeout 5s;# 전체 시간 제한

제한을 두지 않으면 '조금 아픈 상태' 가 '완전히 죽은 상태' 로 넘어간다

면접 함정

  • "nginx가 주기적으로 헬스체크한다" → 오픈소스판은 실제 요청 실패로 판단한다.
  • "ip_hash면 세션이 안전하다" → 서버 증감 시 재배치된다. 세션은 외부에 두는 편이 낫다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 설정 읽기 — server·location·upstream