에러노트

[Ngnix] connect() failed (111: Connection refused) while connecting to upstream 에러 해결

까뮈_b 2022. 6. 27. 15:15

스프링부트를 github action과 AWS CodeDeploy를 이용하여 무중단 배포 환경을 구성하는 도중,

아래와 같은 nginx 에러를 만났다.

nginx error.log 에러 메시지

상세한 에러 메세지는 다음과 같다.

[error] 15761#15761: *47 connect() failed (111: Connection refused) while connecting to upstream, cl"http://127.0.0.1:8080/profile", host: "localhost"

원인

  • upstream(http://127.0.0.1:8080/profile)에%EC%97%90) 접근할 수 없어서 발생하는 오류. 해당 포트번호가 닫혀있는데, 접근하려니 연결에 실패하는 것이다. 해당 포트번호로 부트가 떠있지 않은 상태인데, health check를 하면서 생기는 오류다. 일단 해당 주소:포트번호가 열려있는지 확인해보는 것이 필요하다.

해결

1. 해당 port가 열려있는지, listening 포트를 검색

sudo netstat -plant | grep '80'`

위의 명령어를 수행했을 때 '80'이 포함된 모든 listening 포트 목록이 뜬다.

netstat 결과

나는 1의 과정을 통해, 부트가 8080번이 아닌, 8081번으로 떠있는 것을 알았다.

해결의 실마리를 바로 찾았다.

nginx를 리버스 프록시 서버로 활용하여 무중단 배포 환경을 구축하기 위해, springboot를 포트번호 8081과 8082로 각각 띄우게끔 설정을 바꿔놓고, 헬스체크는 8080으로 보내고 있어서 생긴 문제라고 알아챌 수 있었다.

2. nginx.conf 수정

proxy_pass 의 주소가 http://localhost:8080으로 설정되어있던 부분을, 아래와 같이 $service_url 변수로 변경하였다.

$service_url은 /etc/nginx/conf.d/service-url.inc 파일에서 가져오게끔 구성하였다. 이를 위해 아래와 같이 include 하는 문구를 추가했다.

 service-url.inc 파일은 배포 스크립트를 실행하면서, 8081과 8082 사이에서 port를 전환할 때 새로 작성하게끔 구성했다.

 

해당하는 부분의 배포 스크립트는 아래와 같다. 

  echo "set \$service_url http://127.0.0.1:${IDLE_PORT};" | sudo tee /etc/nginx/conf.d/service-url.inc

  echo "> 엔진엑스 Reload"
  sudo service nginx reload

 

결론

  • [error] connect() failed (111: Connection refused) while connecting to upstream 에러는 upstream의 경로가 올바르지 않아서 접근할 수 없기에 발생되는 에러다. 대부분 해당하는 주소와 포트에 애플리케이션이 제대로 떠있지 않았을 때 이 에러를 마주한다. netstat을 통해 listening port 목록을 확인하고, 어플리케이션단 코드와 nginx.conf 파일을 확인하여 nginx와 애플리케이션의 주소가 서로 일치하는 지 확인하자.