본문 바로가기

참고자료

웹서버 nginx

1. nginx 란 무엇일까

오픈소스에 유료지원도 있는 웹 서버이다. 가볍고 높은 성능을 목표로 하고 있으며  웹서버, 리버스 프록시, 메일프록시 와 같은 기능도 수행할 수 있다. 거의 모든 unix 계열 OS에서 지원되며, windows 에서는 부분적으로 지원이된다.

niginx를 설명하는 키워드들은 event driven 아키텍쳐 / 적은 메모리 사용 / C10K problem의 해결 등으로 말 할 수 있을것 같다.

 

2. nginx 의 대략적인 특징

  •  async event-driven 방식을 사용하는 이벤트 지향 아키텍쳐이다.  메모리 생성 속도가 빠르다.  더 적은 쓰레드로 많은 클라이언트 처리가 가능하다.
  • 환경설정을 바꾼 후 서버 데몬을 재시작할 필요 없이 reload 신호만 보내면 된다. 즉, 프로세스 재시작의 필요가 없다.
  • 로드 밸런싱, TLS/SSL 보안, 메일 프록시 등 아파치 웹서버가 제공하는 모든 기능을 제공한다. 
  • 싱글스레드 + 멀티 프로세스 방식을 사용한다. 프로세스는 master process와 worker process가 있다.
  • master process 는 worker process 를 관리는 역할만 수행하고 woker process 는 싱글 스레드로 구성되어 사용자의 요청에 응답하는 역할을 한다.  이 방식으로 niginx 는 프로세스나 스레드에 대한 지속적인 생성과 파괴가 없어 cpu 절약에 좋다.  
  • nginx는 적은 자원활용과 물리적인 하드웨어를 통한 쉬운 확장으로 주목을 받았다.
  • 정적인 콘텐츠를 처리하는데 빠르다. 동적인 콘텐츠 처리가 느린것도 아니었다. nginx내에서 fastcgi를 설정할 수 있는 것 같다. 그래도 동적 콘텐츠 처리시 동적 처리를 별도로 담당하는 소프트웨어와 연계하여 서비스를 제공하는 걸 추천하는 듯하다. 이때 단점은 동적 콘텐츠를 처리하는 외부프로세서에서 렌더링을 완료하고 전송을 다시 할때까지 기다려야된다는 것이다. 즉, 프로세스 속도 저하가 될 수 있다.
  • nginx 는 프로세스와 스레드의 개념과는 다르게 이벤트의 개념으로 접근하여, 단일 작업자가 동시에 수천 개의 요청을 처리할 수 있다.
  • 모듈을 실행시점에 동적으로 로딩하는것이 불가능하다. 빌드 시점에 사용하고자 하는 모듈또한 같이 포함되어 컴파일이 되어야한다.
  • apache의 mod_jk와 같은 서블릿 컨테이너와의 공식적인 AJP 커넥터를 지원하지 않는다. 

worker process 의 사이클

     1. 네트워크와 스토리지의 상태를 확인한다.

     2. 새로운 연결을 초기화 한다.

     3. 런 루프에 추가한다.

     4. 완료될때까지 비동기적으로 처리한다.

     5. 완료되면 연결이 할당 해제되고 런 루프에서 제거된다.

 worker process 가 일을 처리하기 때문에 worker process 의 수가 중요하다.

일반적으로는 cpu 의 코어의 수만큼 할당을 한다. auto로 설정하면 자동으로 값을 설정한다.

 cpu 집약적인 작업(ex : 다량의 tcp/ip 처리 혹은 ssl 수행, 압축) 의 경우는 cpu 코어의 수와 일치시키고

 연결 요청이 disk 입출력이 많은 작업이라면 cpu 코어의 수의 1~2 배가 권장된다. 

 

3. 왜 niginx 를 써야하는가?

  • 효율적인 서버자원의 사용

CPU 나 메모리와 같은 서버 자원의 대한 고려는 필요하다. 이러한 고려중에는 C10k 문제에 대한 대처도 포함된다. 

C10k 문제란 하드웨어 자원이 충분함에도 IO 처리 방식 문제때문에 프로세스가 제대로 처리하지 못하는 문제를 말한다.

이 C10K 문제를 처음에는 OS  커널을 수정하는 방식으로 하려고 했다.

하지만 select() 와 poll() 의 IO multiplexing 함수가 처리 할 수 있는 fileDescriptor 갯수가 설계 당시부터 10K 이상을 고려하지 않았기 때문에 커널로 해결을 하지 못하였다고 한다.

아파치 웹서버의 경우, 커넥션이 많을수록 성능이 저하된다. 아파치는 하나의 connection 당 하나의 스레드를 처리하는 모델이었고 스레드는 서버 CPU 코어 수에 종속적이었기 때문이었다. 그렇다고 하드웨어를 업그레이트 하기에는 너무 가성비가 좋지 않다. 이런 문제점들은 node.js 나 nginx 와 같은 비동기 프로그래밍의 필요성이 높아지는 원인이 되었다. 

niginx도 C10K 를 해결하기 위해 event-driven 구조로 만든 웹 서버이다. 

고정된 프로세스만 생성하여, 그 프로세스 내부에서 비동기 방식으로 task를 처리한다. 

io 멀티플렉싱 모델이(epoll 과 kqueue 가) 핵심이다. 

 

  • event-driven 처리방식

event-driven 처리 기반 구조는 여러개의 connection을 모두 event handler 를 통해 비동기 방식으로 처리해 먼저 처리되는 것부터 로직이 진행되도록 한다. CPU와 관계없이 모든 IO를 전부 event listener로 미루기 때문에 흐름이 끊기지 않고 응답이 빠르게 진행이 되어 1개의 프로세스로 더 빠른 작업이 가능하게 된다. 

event-driven 방식은 싱글 스레드의 event loop가 계속 돌아가면서 event queue에 요청이 들어오면 요청을 thread pool에 분배하여 넣어 비동기적으로 처리를 한다.

evnet-driven방식을 사용하는 node.js의 event loop 

단점도 존재하는데 event 처리 시간이 길어져 단일 thread 를 점유하고 있게 되면, 다른 event 처리도 늦어지는 blocking현상이 발생하게 된다. 예를 들어 file read/write 작업의 경우가 오랜 시간 스레드를 점유하는 blocking 현상을 초래할 수 있다. 또한 nginx의 third-party modules 들의 처리 시간이 긴 함수도 원인이 될 수 있다.

이를 보완하기 위해 nginx 1.7 버전부터 Thread pool 기법이 고안이 되었다.

worker process 가 긴 작업을 실행해야하는 경우, 직접 실행하지 않고 task queue에 작업을 넘긴다. 

task queue는 thread pool 에서 작업을 수행할 수 있는 스레드에게 작업을 주고, 완료되면 다시 worker process 에게 완료된 결과를 전달한다.

이런 방식을 활용하면 하나의 worker thread 가 blocking 되어도 나머지 worker thread 가 작동하는데 영향이 없기 때문에 blocking 문제를 해결할 수 있다.

 

  • 로드밸런싱

한 서버의 부하를 분산시킨다는건 장점이다. 1대의 서버가 멈춰도 서비스가 중단되지 않으며, 서버를 늘리는 과정에서도 서비스가 중단되지 않는다.

nginx는 로드 밸런싱에 3가지 종류를 사용한다.  round robbin , least-connected , ip-hash이다.

round robbin 은 주어진 서버들을 순차적으로 돌아가면서 선택하는 방법이다.

least-connetcted 는 현재 접속자 수가 가장 적은 서버를 선택하는 방법이다.

ip-hash 는 hash function을 이용하여 클라이언트 ip를 hashing 한 결과에 따라 다른 서버를 할당해 주는 방법이다.

 

 

 

4.nginx 의 작동방식

  1. starting server

master process 가 각종 초기화 작업을 진행한다. 이때 config 파일을 읽고, 포트바인딩을 하며, child process 를 생성한다. child process 에는 cache loader/cache manager/ workcer process 들이 생성된다. 

  • cache loader  : 시작시에 생성되어 disk의 캐시 데이터를 메모리로 복사하는 작업을 한다. 이후 종료 한다.
  • cache manager : 주기적으로 실행되면서 캐시 공간을 정리한다.

 

  2. running

worker process는 싱글스레드로 event queue하나를 가진다. 또 단일 event loop내에서 모든 커넥션에 대한 작업을 처리한다. 각 worker process 당 하나의 loop가 있으며 이 loop가 반복하면서 

커널로 부터 신규로 발생한 이벤트를 받아 큐에 적재하고 큐에 쌓인 이벤트를 하나 꺼내 처리 한다.

 

  3. 커넥션 분배 방식

  • 단일 listen socket의 경우 

기본방식이며 nginx 전체에 하나의 listen socket 에서 요청을 받아 각 worker 별로 돌아가면서 connection을 만들어 던져준다. connection 배분을 위해 lock 리소스가 든다.

 

  • socket sharding(~1.9.1)

 

하나의 포트에 대해 복수개의 소켓을 바인딩 가능할 수 있게 하는 옵션이 있다. SO_REUSEPORT 소켓 옵션이다.

이 옵션을 통해 각 워커당 listen socket을 열어두어 병렬 처리를 할 수 있게 한다.

커널에서 요청을 어느 listen socket가 수락할지는 round robin 형태로 분배를 한다. 

특정 listen socket 에 대해 커넥션을 받을 수 있는 worker 가 1개이다보니 해당 worker가 blocking되는 케이스에서는 신규로 들어오는 요청은 처리가 안되는 단점이 있다. 하지만 그런 경우는 대량 태스크 처리를 다루는 경우라고 한다.

 

 

 

5. 그럼 언제 적절한가?

정적 콘텐츠가 많은 트래픽이 많은 웹 사이트를 실행하는 경우에 적절하다 . 하지만 커뮤니티가 지원하는 자원은 apache가 더 많다. nginx 와 apache 둘 중 무엇이 더 좋다보다는 상황에 따라 적절한것을 선택해야 된다.

  • 또 고려해야 될것은 운영체제이다. windows에 대한 부분지원중에 현재 알려진 문제는 여러개의 worker가 생성되어도 하나의 worker만 작동하는 문제가 있다. 이런것도 참고하자.
  • 요청 처리 및 해석의 방법 차이도 있다. nginx는 요청을 해석하기 위해 URI를 전달한다.
    반면에 apache는 요청을 해석하기 위해 파일시스템 위치를 전달한다.
  • nginx는 동적 모듈과 로딩을 지원하지 않는다. 타사의 플러그인 과정으로 컴파일되기 때문이다.
    반면 apache는 지원한다.
  • 기능 모듈의 차이도 있는데, nginx는 동적모듈을 사용하지 않기 때문에 사용하려는 기능만 선택해서 서버를 실행시켜야한다. 즉 가볍다.
    반변 apache는 동적으로 로드 가능한 공식 모듈이 많다. 하지만 가지고 있는 모듈에 비해 실제 사용되는 모듈이 적어 무겁다는 특징이 있다.
  • 보안적인 부분은 두 웹서버 모두 c언어 기반으로 확장된 보안을 지원한다고 한다. 다만 nginx가 코드가 더 작기 때문에 미래 지향적인 보안 관점에서 장점이 있다고 한다. 보안면에서는 nginx가 조금 더 좋다. 

 

 

 

 

 

참고자료

nginx fastcgi https://minholee93.tistory.com/entry/Nginx-FastCGI-Cache

nginx 이해하기 및 기본 환경 https://whatisthenext.tistory.com/123

apache 와 niginx 차이 https://sorjfkrh5078.tistory.com/289

nginx의 작동 원리 https://zin0-0.tistory.com/295

nginx의 개념과 작동방식 정리 https://jizard.tistory.com/306

nginx에 대한 정리2 https://developer88.tistory.com/299

nginx 동작 흐름 https://eminentstar.tistory.com/74

웹서버에(apache, niginx) https://gpffh1011.tistory.com/60

c10k 부터 evenet-driven까지 https://applefarm.tistory.com/137

마소394호 소식 관련 기사 http://it.chosun.com/site/data/html_dir/2018/10/30/2018103002778.html

nginx 이해 https://kbs4674.tistory.com/126

nginx 와 apache 비교 https://velog.io/@ksso730/Nginx-Apache-%EB%B9%84%EA%B5%90

nginx 와 apache 비교 https://centbin-dev.tistory.com/44

nigix와 관련된 정리 https://hyeo-noo.tistory.com/205

nginx 웹 서버란 https://raonctf.com/essential/study/web/nginx

https://niklasjang.tistory.com/56

'참고자료' 카테고리의 다른 글

API와 SDK  (0) 2022.04.14
blocking 과 non blocking  (0) 2022.01.27
포워드 프록시 와 리버스 프록시  (0) 2022.01.26
EC2 에 mysql 8.0 설치하기  (0) 2021.10.20
자바 8 과 자바 11의 특징  (0) 2021.10.14