조회수: 3

no live upstreams (nginx 502)

no live upstreams는 nginx가 업스트림 풀 전체를 사용 불가로 표시해 낸 502입니다. 헬스체크 축출인지 설정 함정인지 진단하세요. 무료 즉시 진단.

내 도메인에 이 문제가 있는지 지금 확인

무료, 가입 불필요. 이 가이드가 다루는 항목을 바로 검사하고 조치 방법을 알려드립니다.

문제

요청이 502 Bad Gateway를 반환하고 nginx 에러 로그에 no live upstreams while connecting to upstream이 찍혀 있습니다. 이건 백엔드 하나가 연결에 실패한 것과 다릅니다. nginx가 업스트림 그룹 전체를 보고 그 안의 모든 서버가 그 순간 요청을 받을 자격이 없다고 판단해 — 프록시할 대상이 없어 — 연결을 시도하지도 않고 502를 냈다는 뜻입니다. 먼저 답할 질문은, nginx가 당신의 서버들을 축출한 것인지(수동 헬스체크가 전부 쳐냄) 아니면 설정이 애초에 라우팅할 대상을 안 남긴 것인지입니다. 이 둘은 완전히 다른 버그이기 때문입니다.

증상

  • 클라이언트는 밋밋한 502 Bad Gateway를 보고, nginx 에러 로그에 no live upstreams while connecting to upstream이 뜹니다.
  • curl로 직접 때리면 백엔드는 멀쩡히 응답합니다 — 문제는 앱이 아니라 nginx의 라우팅 판정입니다.
  • 백엔드가 여럿이면 간헐적이고 부하 스파이크와 맞물립니다 — 몇 초 튀었다가 저절로 풀립니다.
  • 백엔드가 하나면 설정 키워드(down·backup·max_conns)나 DNS/resolver 실패에 묶여 있고, 앱을 아무리 재시작해도 바뀌지 않습니다.

이 에러의 실제 의미

nginx는 upstream 블록의 각 서버에 대한 판정을 계속 유지합니다. 서버를 둘 이상 나열하면 수동(passive) 헬스체크를 돌립니다 — 실제 프록시된 요청을 지켜보다가, 한 서버가 fail_timeout 안에 max_fails회 실패하면 사용 불가로 표시하고 fail_timeout이 만료될 때까지 우회한 뒤 조심스럽게 다시 시도합니다. 기본값이 공격적입니다 — max_fails=1, fail_timeout=10s — 그래서 단 한 번의 실패로도 서버가 10초간 벤치됩니다.

no live upstreams는 그룹의 모든 서버가 동시에 벤치됐을 때 nginx가 남기는 로그입니다. 자격 있는 피어가 하나도 안 남아 연결을 시도조차 못 하고 502를 냅니다. 이게 미스터리처럼 보이는 이유가 여기 있습니다 — 당신이 백엔드에 curl을 날릴 즈음엔 fail_timeout이 지나 다 “멀쩡”하지만, 그 창 동안엔 나쁜 순간 하나가 풀 전체를 쓸어버린 것입니다.

부하 중 이게 연쇄되는 방식이 사람들이 놓치는 지점입니다. 트래픽 스파이크가 한 백엔드를 max_fails를 넘길 만큼 느리게 만들고, nginx가 그걸 벤치하면서 그 몫을 생존자에게 밀어넣고, 늘어난 부하가 다음 서버를 넘어뜨리고 — 1~2초 안에 모든 서버가 걸려 그룹 전체가 fail_timeout 동안 죽습니다. 실제로는 아무도 크래시하지 않았는데도요. 지나치게 예민한 기본값으로 스스로 만든 장애입니다.

단독 서버 케이스: max_fails가 아니다

사람을 엉뚱한 길로 보내는 함정이 여기 있습니다. 업스트림 블록에 서버가 정확히 하나면 max_fails·fail_timeout 튜닝은 아무 것도 안 합니다 — nginx가 무시하기 때문입니다. 업스트림 모듈 문서에서: “그룹에 서버가 하나뿐이면 max_fails, fail_timeout, slow_start 파라미터는 무시되며, 그런 서버는 절대 사용 불가로 간주되지 않는다.”

즉 단독 백엔드는 수동 헬스체크로 축출되지 않습니다. 서버가 하나인데 no live upstreams가 뜬다면 원인은 다른 데 있고, 거의 항상 이 중 하나입니다.

  • 서버가 down으로 표시됨. server 줄에 남은 down(또는 그걸 붙인 설정 템플릿)이 있으면 nginx는 영구 사용 불가로 봅니다. down 서버 1개 = 살아 있는 서버 0개.
  • max_conns 포화. 서버의 동시 연결 수에 상한을 걸었고 그게 다 찼다면, nginx는 새 연결을 열 슬롯이 없어 그 서버를 not live로 셉니다.
  • 전부 backup. 모든 항목이 backup인데 primary가 없으면 서비스할 살아 있는 primary가 없습니다 — backup은 primary가 죽을 때만 활성화되는데, 그 primary가 없는 것입니다.
  • resolver/변수 업스트림 해석 실패. 업스트림 주소가 요청 시점에 해석되는 변수인데 DNS 조회가 실패하면, nginx는 연결할 주소가 없어 no live upstream으로 보고합니다.

각각은 헬스체크 튜닝 문제가 아니라 설정·DNS 문제입니다. 여기서 max_fails=3을 만지는 건 아무 것도 못 고칩니다.

DechoNet으로 진단하기

  • HTTP 점검은 바깥 세계가 실제로 무엇을 받는지 — 최종 상태가 nginx발 502인지 — 확인하고, 실패하는 경로와 되는 경로를 비교하게 해줍니다. 502가 간헐적이면 반복 점검으로 부하와 상관 있는지(연쇄)인지 상시 발생인지(설정 함정) 볼 수 있습니다. nginx 에러 로그의 정확한 문구와 짝지어 보세요 — 그게 진짜 진단 열쇠입니다.

해결 체크리스트

  • 정확한 로그 문구를 먼저 읽으세요. no live upstreams(그룹 전체 사용 불가)는 connect() failed·upstream timed out(한 번의 시도 실패)와 다른 버그입니다. 엉뚱한 걸 고치지 마세요.
  • upstream 블록의 서버 개수를 세세요. 하나 → max_fails아닙니다. down·backup·max_conns·resolver 실패를 확인. 여럿 → 수동 헬스체크 축출을 의심.
  • 다중 서버 연쇄라면 예민한 기본값을 완화하세요 — max_fails(예: 3)와/또는 fail_timeout을 올려 한 번 느린 순간이 멀쩡한 서버를 벤치하지 않게 하고, 백엔드가 느렸던 근본 원인(포화·타임아웃·GC 멈춤)을 고치세요.
  • 설정에서 남은 down 하나, 그리고 모든 항목이 backup이고 primary가 없는 블록을 grep하세요. 남은 down은 제거하고, 그룹에 실제 primary를 주세요.
  • 업스트림이 변수+resolver를 쓴다면 resolver가 도달 가능한지, 이름이 해석되는지 확인하세요 — 여기서의 DNS 실패가 “no live upstreams”로 읽힙니다.
  • HTTP 점검을 다시 돌려 해당 경로가 더 이상 502를 반환하지 않는지 확인하세요.

언제 에스컬레이션할까

  • 502가 트래픽 스파이크를 따라 fail_timeout 안에 풀린다면, 진짜 문제는 nginx가 아니라 업스트림 용량·지연입니다 — max_fails만 넓히지 말고 포화·느린 쿼리·커넥션 풀 한도·백엔드 타임아웃을 파세요.
  • 관리형 로드밸런서나 인그레스 컨트롤러 뒤에서 nginx를 돌린다면, 자체 임계값을 가진 헬스체크 계층이 하나 더 있을 수 있습니다 — 한 계층엔 “정상”인 백엔드가 다른 계층엔 벤치돼 있을 수 있습니다.
  • 백엔드 하나가 응답 헤더가 nginx 버퍼를 넘쳐 502가 나는 밀접한 케이스는 upstream sent too big header (nginx 502)를, 502 일반 결정 트리는 502 Bad Gateway 체크리스트를 보세요.

관련 도구

관련 가이드

가이드 공유

[Ad] Guide Detail Inline
← 전체 가이드 보기