NGINX란 무엇인가?
Nginx는 오픈소스이고 웹 서버와 리버스 프록시 SW이다. 아파치와 마찬가지로 HTTP 요청을 처리하고 다른서버로의 요청을 전달한다. 아파치에 비해 기능은 적지만 경량화 되어있어 EC2 프리티어에서 잘돌아가도록 사용할 수 있다. 즉, 고성능과 높은 안정성을 제공한다.
리버스 프록시란
? 서버 앞단에서 문지기와 같은 존재, 트래픽 분산과 보안, 캐싱 처리에 좋다. (밑에서 설명예정)
반대로포워드 프록시
개념은 정부나 보안이 높은 기관에 속한 사람들의 인터넷을 제한적으로 사용할떄 쓰는 개념이다.
NGINX와 아파치의 차이점
아파치는 클라이언트의 요청이 들어올때마다 하나의 프로세스를 만든다. 프로세스를 만드는 작업에서 많은 시간이 소요되다보니 PREFORK
방식으로 요청이 오기전에 미리 프로세스를 만드는 방식으로 구성되어있다. 하지만, 이러한 구조는 동시에 엄청나게 많은 커넥션이 있을때, 메모리 부족을 야기한다. 그래서 나온 개념이 Nginx
이다.
※ 참고로 prefork MPM방식 외에도 Worker MPM라는 방식으로 요청을 할 수 있다.
Nginx
는 이벤트 기반 처리 구조방식이다. 아까 말한 수많은 커넥션의 메모리 부하를 크게 줄이는 취지에서 나온 웹서버이다.
위의 그림에서 PREFORK 방식을 보면 커낵션마다 프로세스를 만드니까 요청이 많으면 💣하고 메모리가 터질 수 있다. 그럼 도대체 이 많은 커낵션을 어떻게 유지하냐? 비결은 Master process
에 있다. cd /etc/nginx/~/ ??.confg 하고 들어가면 있는 설정파일을 읽고 그에 맞는 worker process
를 만든다. 그리고 그에 맞는 listen 소캣을 배정받는다. worker process
는 보편적으로 CPU 프로세스 수만큼 master
가 생성하고 관리한다.
공홈에서 가져온 이미지인데 잘 안보이지만 핵심은 Master process, cache loader, cache manager, worker
이다.
Nginx
에서는 커넥션의 생성, 제거, 처리를 이벤트
라고 한다.
이러한 이벤트는 OS커널에서 큐형식으로 worker process
에게 전달한다. 이런 이벤트들이 하나의 큐상태로 비동기상태로 대기를 하고 있고 worker process
는 이벤트를 poll()
하며 하나씩 해결해 나아간다. 이러한 방식은 커넥션 낭비현상
을 줄여주게 된다.(PREFORK 방식에서는 프로세스는 할당되어있는데 놀고있는 상태가 생길 수 있다.)
하나의 이벤트, 즉 큐에 담겨있는 하나의 요청이 다른 큐들에 비해 처리속도가 길면 그 자체로 손해아닌가?
라는 질문이 생길 수 있다. Nginx는 이것 또한 해결할 수 있게 구상을 하였다. Thread pool
에 따로 이러한 요청을 처리하는 공간을 마련해두어, 설정을 통해 일정시간 오래 걸리는(용량이 큰)이벤트를 worker process
가 Thread pool
에게 위임을 하고 큐에 담긴 다른 이벤트를 처리하는 방식으로 문제를 해결한다.
이번 프로젝트에서 NGINX를 도입한 이유
낮은 EC2 메모리 성능과 은근 많이 사용되는 css, js의 정적페이지를 빠르게 제공을 위해서, 그리고 SSL 인증서를 발급받기 쉬워서? 이다. (그리고 대세이기도 하고….)
위처럼 nginx.conf에서 캐싱설정이나 (동적 캐싱은 redis를 사용하기 때문에 따로 안했다) proxy 설정을 쉽게 할 수 있고 Let’s Encrypt를 사용하면 무료로 SSL을 발급시켜주고 인증서를 자동으로 등록시키고 발급해준다. 90일이라는 유효기간이 있지만 이 또한 갱신이 쉬워서 많이들 사용한다.
Nginx의 SSL 터미네이션
브라우저와는 https로 연결하고 서버와의 통신에서는 http로 통신하는 방법이다. 컴퓨터의 성능이 아무리 좋아졌지만, 복호화를 하는 과정은 서버에게 부담이 될 수 밖에없다. 비즈니스 로직에 좀 더 힘을 쓸 수 있도록 구성한 방식이다. http 통신을해서 위험하지 않냐? 라는 의문이 들수도 있지만 하나의 컴퓨터 또는 하나의 네트워크 안에서 통신하기 떄문에 http 통신의 위험 요소가 적다.
Nginx config 설정을 바꿀떄마다 restart를 무조건해야하나?
우선 정답부터 말하면 그럴필요없다. nginx -s reload
나 systemctl reload nginx
를 통해 기존 연결이 종료되지 않고 변경사항이 적용된다. 이유는 Nginx는 이벤트 기반 구조로 형성이 되어있어. 개발자가 설정파일을 변경하고 nginx에 적용하면, Master process
가 새로운 worker process
를 만들어서 해당 설정에 맞는 woker process
를 따로 생성한다. 그러면서 기존의 유지되고 있던 커넥션들을 더 이상 사용할 수 없도록 관리해준다. 이런점이 로드 밸런서의 역할을 통해 무중단 배포를 할 수 있는 환경을 제공하는 것이다.
이 링크는 Nginx 커스텀 기본세팅을 알려주는 사이트인데 개인적으로는 공식홈피나 블로그를 참고해서 설정하는게 더 빠르고 쉬운거같다.