Nginx란 무엇인가?
회사 업무에 있어서 Nginx 와 같은 인프라를 전혀 모르기에 어떤식으로 이루어져있는지
어떻게 등장하게 되었는지 왜 사용하는지?에 대해서 공부한 내용을 정리해 보았다.
내용은 유튜브를 참고하여 정리한 내용으로 출처는 하단을 참고하면 된다.
Nginx의 등장배경
Nginx의 등장을 알기 위해서는 왜 등장하게 되었는지 그 전의 배경부터 알아야 한다.
1995년 유닉스 기반으로 만들어진 최초의 웹서버 NCSA HTTPd 가 있었으나 버그가 굉장히 많아서 구조를 변경하고 기능을 추가해서 만든 것이 Apache Server(아파치 서버)다.
* Web Server : 정적인 파일을 응답
* Web Application Server : 클라이언트의 요청에 대해 동적인 처리가 이뤄진 후 응답
아파치 서버는 Request 요청이 들어오면 Connection 형성을 위해 Process를 생성한다.
클라이언트의 새로운 요청이 들어올 때마다 새로운 프로세스를 만드는 구조를 갖고 있었는데 이는 유닉스 계열 OS가 네트워크 커넥션을 형성하는 모델을 그대로 적용한 것이라고 한다.
그러나 프로세스를 만드는 것이 리소스를 많이 사용하는 일이다보니 미리 프로세스를 만들어놓고 새로운 요청이 들어올 때마다 미리 만들어 놓은 프로세스를 할당해주는 Prefork 방식을 사용하였다.
이를 통해 확장성이 좋아 모듈화를 통해 서버에 빠르게 기능을 추가하고 동적 컨텐츠를 처리할 수 있었다.
확장성 덕분에 요청을 받고 응답을 처리하는 과정을 하나의 서버에서 해결하기 좋아 아파치 서버가 인기를 얻게 되었다.
그 이후 1999년 부터 점점 인터넷 보급이 활발해지면서 트래픽이 많이 증가하게 되고 동시에 연결된 커넥션이 많아졌을 때 더이상 커넥션을 형성하지 못하는 C10K 문제가 발생하게 되었다.
(* Connection 10,000개의 문제라는 의미)
요청이 들어오면 프로세스를 처리하고 연결된 커넥션이 바로 종료가 되는 것이 아니라 어느정도 텀이 있었고 동시에 연결된 커넥션이 점점 많아질수록 서버에 부하가 커져갔다.
커넥션을 형성하는데 여러 절차들이 있어 이미 만들어진 커넥션이 있다면 이를 재활용하고자 했고 http header에 keep-Alive에 따라 클라이언트와 서버는 연결을 유지하고 있게 된다. 그만큼 초당 요청이 많아질수록 동시에 연결된 커넥션의 수는 더더욱 많아지게 되는 것이다.
이때 동시 커넥션 수가 10,000개를 넘어가는 순간 서버는 더 이상 커넥션을 형성하지 못하는 문제가 대두되었고 하드웨어나 그 당시 웹페이지의 컨텐츠 크기를 보면 서버 구조의 문제라고 할 수 있다.
이러한 아파치 서버의 구조로 인해 Context Switching 이 빈번해져 CPU의 부하가 늘어났고 수많은 동시 커넥션을 감당하기에는 아파치 서버의 구조가 적합하지 않았다.
Nginx의 등장
2004년 아파치 서버의 문제를 보완하기 위한 소프트웨어로 Nginx가 나오게 되었다.
초창기에는 아파치 서버의 한계를 극복하기 위해 Nginx를 함께 쓰는 방식으로 활용되었고 아파치 서버의 앞단에서 동시 커넥션을 Nginx가 대신 유지하여 아파치 서버의 부하를 줄여주고 Nginx는 그 자체로 Web Server 이기 때문에 정적 파일에 대한 요청을 처리할 수 있었다.
동적 파일 요청을 받을 때에만 아파치와 커넥션을 형성했고 아파치 서버의 리소스를 커넥션 유지에 쓰지 않고 개발자가 원하는 로직 처이세 쓰도록 해주었다.
Nginx의 구조
Nginx는 Master Process 아래 Worker Process 가 있고 요청이 들어온 커넥션에 대해 처리하고 Keep-Alive 만큼 유지한다.
그러나 아파치 서버처럼 하나의 프로세스가 하나의 커넥션만을 담당하고 있는 구조가 아니라 일을 처리하고 대기하는 상태에서는 새로운 커넥션을 형성하거나 다른 커넥션으로부터 들어온 요청을 처리한다.
즉, 하나의 프로세스가 하나만을 담당하던 아파치 서버와는 달리 하나의 워커 프로세스(Worker Process)가 여러개의 요청을 처리한다.
커넥션 형성, 제거, 요청 처리 등을 이벤트(Event)라 부르는데 이 이벤트들은 OS 커널이 큐 형태로 워커 프로세스(Worker Process)에 전달한다.
이렇게 되면 기존 아파치 서버에서처럼 하나의 프로세스가 매칭되어 일을 처리하고 있지 않은 대기상태로 있는 것을 방지하고 워커 프로세스가 쉬지 않고 일을 처리할 수 있게 한다.
만약 이 큐 안에서 오래걸리는 요청이 있다면 오래 걸리는 요청들만 처리하는 쓰레드 풀(Thread Pool)로 이벤트를 위임하여 큐 안에서 오래 걸리는 요청으로 인해 발생할 수 있는 Blocking 을 방지한다.
그리고 CPU의 코어 수 만큼 Worker Process를 생성하여 CPU 코어가 담당하는 프로세스를 스위칭하는 컨텍스트 스위칭을 대폭 줄여 부가적인 CPU사용 및 부하를 줄일 수 있다.
* 아파치 서버와 가장 큰 차이점
만약 서버가 동작중일 때 설정 파일을 변경하고 적용하면 Master Process는 그 설정에 맞는 Worker Process를 따로 생성하고 기존의 Worker Process가 더이상 커넥션을 형성하지 않도록 한다. 기존의 Worker Process의 이벥트처리가 모두 끝나면 해당 프로세스를 종료하는 방식으로 가동중 설정을 변경, 적용 할 수 있다.
Nginx의 점유율
초반의 점유율이 낮았던 Nginx는 2008년 스마트폰의 시대가 되고 실시간으로 많은 컨텐츠 요청을 받게되었다.
웹에 담기에는 컨텐츠가 다양해지고 용량이 커지면서 브라우저도 여러 리소스를 빨리 가져오기 위해 여러 TCP커넥션을 동시에 형성하기 시작했고 각각의 커넥션은 모두 Keep-Alive 설정으로 유지되었다.
결국 동시 커넥션 문제를 처리해야할 서버가 많아졌고 덕분에 Nginx가 인터넷 트래픽에 관여하는 비중은 높아졌다.
Nginx를 사용하는 이유 (장점)
1. 빠르다
- Nginx는 메모리 사용을 효율적으로 하여 50개의 동시 커넥션이나 3000개의 동시 커넥션이나 메모리 사용량에 큰 차이가 없다.
- 초당 요청 처리는 동시 요청자가 많아도 다른 것들에 비해 상당한 성능을 낸다.
- Nginx는 그 자체로 웹서버와 로드 밸런서 역할을 하지만, 가볍다는 장점을 살려 웹 서버 가속기 역할도 한다.
- 비즈니스 로직 처리에 리소스를 사용할 수 있도록 부하를 줄요준다.
2. 리버스 프록시로 사용 가능 (Reverse Proxy)
- 리버스 프록시는 인터넷과 백엔드 사이에 있는 서버를 의미한다.
- 리버스 프록시를 사용하면 Nginx가 로드 밸런싱(Load Balancing)을 할 수 있다.
- 한번 서버로부터 받은 응답을 보관하고 클라이언트에게 전달하는 캐싱 서버(Caching Server)로 이용할 수 있다.
- Nginx가 중요한 정보들을 숨겨주는 보안 역할을 할 수 있다.
- Nginx는 보통 서버와 같은 네트워크 안에 있는 경우가 많기 때문에 이 둘은 http 통신을 해도 비교적 보안적인 위험이 적다.
3. SSL 지원
- '우리 사이트는 보안 처리가 잘 되어있다' 라고 인증 해줄 수 있는 것이 SSL인증서인데 Nginx가 HTTPS의 인증서를 제공해줄 수 있다(쉽게 설정 가능).
4. 웹페이지 접근 인증
- 사용자가 로그인을 시도할 때 로그인 정보가 올바른 정보인지 WAS에서 검증할 수 있는데 WAS에서 하지 않고 Nginx에서도 할 수 있다.
5. 압축
- 클라이언트가 보내는 요청이 text일 때 그 데이터들을 압축 시켜줄 수 있다.
- text/css, javascript, json, text/plain, xml 등등
6. 비동기 처리
- 아파치 같은 경우 클라이언트의 요청들 마다 각 하나의 프로세스가 할당 받게 되어 많은 클라이언트의 요청을 동시에 처리할 수 없지만 Nginx는 이벤트 루프 라는 방식을 사용하여 비동기식 처리를 해주기 때문에 많은 요청에 대해 처리할 수 있다.
이 이외에도 HSTS, CORS 처리, TCP/UDP 커넥션 부하 분산, HTTP/2 지원 등 많은 방식으로 서버를 지원한다.
요약
Nginx는 동시에 많은 요청을 처리해야하는 경우 초당 요청이 증가해도 다른 방식에 비해 리소스 사용량의 차이가 거의 없다는 이점이 있다.
그 자체로 웹 서버이면서 로드 밸런서 역할도 하고 캐싱도 가능하며 웹 서버 가속기와 SSL 터미네션 수행, CORS 처리 등등의 장점으로 사용한다.
'백엔드' 카테고리의 다른 글
JPA Annotations JPA 어노테이션 (0) | 2022.01.17 |
---|---|
Spring Boot JPA란? (0) | 2022.01.17 |