nginx, 왜 사용하는 것일까?

oswaldeff·2022년 9월 21일
0
post-thumbnail

intro

웹서버를 사용함으로서 얻는 장점으로는 리버스 프록시로 정적 콘텐츠 서빙하여 부하 감소라든지 내부 서버의 설정에서 load balancing을 통해 확장성을 가진다는 것인데, 그 사용옵션에 있어서 nginx는 왜 사용하는 것인지 궁금했다.
(study자료로 테코톡 영상을 특히 참조하였습니다)

apache

분명 알기로는 nginx 이전에는 apache를 사용했었고 현재도 여전히 많이 사용하는 웹서버인데 어떠한 계기로 nginx가 부상하게 되었는지부터 조사해보았다.

아파치의 기원

아파치가 이전, 유닉스 기반의 공공HTTP서버라고 불린 NCSA HTTPd1가 존재하였지만
많은 버그들2로 인해 몇몇의 개발자들이 NCSA HTTPd를 계승하여 패치(a patchy)를 적용했고 이를 아파치 서버(a patchy server)라고 하게 되었다고 한다.

1995, 아파치 웹 서버

아파치는 요청이 들어오면 아래와 같이 커넥션을 형성하기 위하여 프로세스를 생성하는데,

Request → [connection] → Process

이는 유닉스계열 os가 네트워크 커넥션을 형성하는 것을 그대로 적용한 아키텍쳐이다.

Request → [connection] → Process
Request → [connection] → Process
.............. → ..................... → Process(preforked)

그런데, 새로운 클라이언트가 request할때 process를 만드는 것이 오래걸려
아파치에서는 새로운 request가 들어오기 전에 미리 process를 만들어 두는 prefork방식이 차용되었다.
(미리 만들어놓은 process들이 할당(connection)된 경우에는 새로운 process를 형성)
(현시대에는 MPM 덕택에 이벤트 방식도 사용가능하다고 한다)

이처럼 아파치는 프로세스 기반 접근방식으로 하나의 스레드가 하나의 요청을 처리하는 구조였으며, 아키텍쳐에서는 정적&동적 컨텐츠를 포함하여 기본적인 HTTP요청과 같은 다양한 모듈들을 적용할 수 있어, 개발자들은 서버에 빠르게 모듈을 추가할 수 있었다.

즉 아파치 개발로 인하여 요청(request)을 받고 응답(response)을 하는 과정을 하나의 서버에서 손쉽게 처리할 수 있게 되었다는 뜻이다.

1999, 많은 리소스 소비(c10k)

시간이 흐름에 따라 컴퓨터의 보급에 많아졌고
서버에 동시에 연결된 connection이 많아졌을때 더이상 서버에서 새로운 connection을 형성하지 못하는 일이 발생했다.
이를 c10k problem(10 thousand connection problem)이라고 일컫는다.

초당 요청 처리수와는 다른, 동시에 연결된 커넥션 수

초당 요청 처리수라는 것은 서버가 얼마나 빨리 요청을 처리할 수 있느냐라는 것을 나타내는 지표이며 connection이란 클라이언트와 연결된 상태를 나타내므로,
결국 동시에 연결된 커넥션 수라는 지표는 동시에 서버에 물려 감당할 수 있는 클라이언트의 수를 지칭하는 것인데,

10client x 10 request = 100
1client x 100 request = 100

(위와같이 연결된 클라이언트가 다를지라도 요청 수는 같을 수 있다)

connection이 연결되는데에는 여러 절차들이 있었으며,
(IP/TCP/HTTP protocol)
이에따라 매 request마다 connection을 새로 형성하기에는 번거롭고 비효율적이었기 때문에 이미 만들어진 connection을 재활용하는 방법을 사용하였다.
(http header의 keep-alive3)

이렇게 connection을 재활용하더라도 지속적으로 client가 증가할 경우,
서버는 더이상 connection을 형성하지 못하게되는 문제에 놓이게 되었다.

당시 하드웨어적인 측면에서의 성능은 충분했지만,
아파치는 다중 스레드 접근방식이었기 때문에 각각의 스레드는 하나의 단일연결만 처리할 수 있었다.

결과적으로 connection이 증가하면 새로운 프로세스를 형성하고 이는 곧 메모리 부족으로 이어졌다.

더군다나 아파치 프로그램 자체의 확장성으로 인해 새로운 프로세스가 차지할 리소스가 넉넉하지 않았기 때문에, CPU코어는 계속해서 process를 바꾸어가며 일을 해야했고 이는 CPU부하라는 이슈를 낳았다.
(context switching)

nginx

2004, event-driven의 구조로 적은 리소스 소비

아파치 서버에 대한 구조의 개선과 성능이 지속적으로 향상되었고,
아파치의 동시요청에 대한 구조적 한계를 보완할 목적으로 nginx가 개발되었다고 한다.

Request → Nginx → Apache

(위는 초기 nginx의 역할)

이때 nginx에서는 정적파일에 대한 요청을 처리하고 동적파일에 대한 요청을 받았을 때만 아파치와 커넥션을 형성한다.

nginx이 특징점인 점은 이벤트 중심 접근방식으로 하나의 스레드내에서 여러요청을 처리하는것인데,

.......................................... Master Process
.....................................................↓
Request → Connection(1) → Worker Process(1)
Request → Connection(2) → Worker Process(1)
Request → Connection(3) → Worker Process(1)

기존에 형성된 connection(1)에 추가적인 request가 없다면
동일 worker process(1)에서 새로운 connection3을 형성하기도 하고
이미 만들어진 connection(2)에서 다른 요청이 들어올 경우
해당 요청 또한 동일한 worker process(1)에서 처리한다.
이때 새로운 요청을 처리하는 것이벤트라고 한다.

또한 nginx는 이러한 일련의 이벤트들에 대하여 비동기적으로 처리하는데,
이는 기존 apache에서, 더이상 추가적인 요청이 없을때 방치되던 프로세스에
비해 결국 서버 자원을 효율적으로 쓸 수 있음을 의미했다.

일반적으로 nginx에서 worker process는 서버의 CPU 코어수만큼
생성하는데, 이는 코어 한개에 worker process가 맞물려 있는 형태이기 때문에 코어가 담당하는 process에 대해 switching하는 횟수를 줄일 수 있고 다시말해 CPU부하가 아파치에 비해 작다는 장점을 만들어준다.

다만 확장성에서는 제한적인 부분이 존재

하지만 nginx는 process의 그 특징으로 인하여
만약 개발자가 새로운 기능을 추가하여 서버에 업데이트한다면
기존에 서비스되고 있던 서버에 대해 기존의 worker process가 종료될 수 있고 이는 곧 기존 worker process의 connection에 대해 관련요청들을 더이상 수행할 수 없을 가능성을 내포한다.

또한 nginx는, NCSA HTTPd를 이어온 아파치가 여러 os에 대해 호환성과 확장성을 가지고 있는데 비해, 윈도우에서는 제대로 된 성능을 발휘하지 못하는 제한적인 부분이 존재한다.

remark

1: 일리노이 대학교 국립 슈퍼컴퓨팅 응용센터(NCSA)에서 개발했기 때문에 명명되었다, NCSA HTTPd웹서버 이전에는 c기반의 CERN HTTPd가 존재하였다.
2: NCSA 프로젝트의 리드 개발자가 빠지면서 NCSA HTTPd는 웹사이트 관리자들(개발자들)에 의해 수정되기 시작하며 호환되지 않는 버전들이 양산되었다.
3: 서버는 keep-alive에 기술된 timeout시간만큼 connection을 유지한다.

more keywords for study

#web server #web server application #three-way handshake #http protocol #context switching

0개의 댓글