본문 바로가기
프로그래밍/Web Basic

NginX 웹서버 정리 2

by YuminK 2023. 11. 17.

엔진엑스는 높은 동시성과 퍼포먼스를 타겟팅한다. 웹 서버의 기능에 로드밸런싱, 캐싱, 대역폭 컨트롤 그리고 다른 다양한 어플리케이션과의 통합을 지원한다. 이러한 다양한 통합 기능들이 웹 사이트 아키텍처를 위한 좋은 선택이 되었다. 엔진엑스는 세계에서 2번째로 인기있는 오픈소스 웹서버이다.

 

스마트폰의 등장으로 더욱 많은 트래픽이 필요했으며 비즈니스 생태계가 급진적으로 변화하였다. 인기 있는 웹사이트에서 수십만 수 백만 유저의 동시성을 유지하는 것은 일반적인 상황이었다. 동시성에 대한 주요 이슈는 느린 사용자였고 요즘은 모바일 클라이언트와 뉴스, 트윗, 친구들의 피드 같은 지속적 연결을 유지하길 원하는 새로운 어플리케이션 아키텍쳐로 인해 야기된다. 또한 현대 브라우저의 방식이 빠른 로드 속도를 위해 4~6개의 연결을 1개의 웹사이트에서 처리하기 때문이다. 

 

클라이언트에 1명에게 1MB의 메모리가 할당될 때, 1천명의 경우 1GB의 메모리가 할당 된다. 운영체제의 소켓 버퍼를 늘림으로써 어느 정도 해소할 수 있지만, 일반적인 해결책이 아니며 사이드 이펙트를 발생시킬 가능성이 있다. 게다가 대역폭이 낮을수록 클라이언트는 더욱 느려진다.

 

지속적 연결에 따라 동시성을 처리하는 문제는 더욱 명확해진다. 증가된 처리량을 제어하기 위해 더 효율적인 블록이 필요하다. 아파치의 아키텍처는 1990년대 존재하는 OS와 하드웨어에 잘 맞았다. 전형적으로 아파치 싱글 인스턴스로 돌아가는 인터넷과도 마찬가지다. 2000년대 초 독립형 웹서버 모델은 성장하는 웹 서비스의 니즈를 충족시키기 어렵다는 것이 명확해졌다. 아파치는 각 커넥션에 대한 카피본을 늘리는 방향을 제시했으나 비선형 규모의 웹사이트에는 맞지 않았다. 결국 아파치는 다양한 기능과 서드파티 확장들을 갖춘 범용 웹서버가 되었다. 어떠한 웹 개발에도 사용될 수 있을 정도의 확장성을 갖추게 된다.

 

그러나 풍부하고 범용적인 조합이 가능한 아파치는 연결당 CPU 사용량과 메모리 사용에서 확장성이 낮았다. 서버 하드웨어, 네트워크 리소스, 운영체제가 더 이상 웹사이트의 성장에 제약이 되지 않을 때, 웹 개발자들은 더 효율적인 방식을 찾기 시작했고 Daniel Kegel라는 개발자는 말했다. "it's time for web servers to handle ten thousand clients simultaneously" 웹 서버는 1만개의 연결을 처리할 때가 되었다.

 

이에 따라 많은 수의 연결에 대해 웹 서버를 최적화 하는 방안이 촉구되었고 nginx는 가장 성공적인 케이스가 되었다.

 

nginx의 방식은 동시 연결수와 초당 요청수 모두에서 비선형 확장에 더 적합했다. 이벤트 기반이며 아파치의 프로세스/스레드 생성 방식을 따라가지 않았다. 처리수가 늘어나도 메모리와 CPU 사용량을 일정하게 유지된다. nginX는 일반적인 하드웨어를 갖춘 서버에서 C10k문제를 해결한다.

 

처음 nginX가 출시될 때, HTML, CSS, JS같은 정적 컨텐츠와 이미지를 처리하고 아파치 기반의 어플리케이션 서버에서 동시성과 응답 속도부분에 짐을 줄이기위함이었다. 개발과정에서 fastCGI, uswgi, scgi 프로토콜을 통한 어플리케이션 통합 기능이 추가되었고, memcached같은 분산 메모리 오브젝트 캐싱 시스템이 추가되었다. 로드밸런싱과 리버스 프록시 그리고 캐싱 또한 추가되었으며 이러한 기능들은 nginx를 확장 가능한 웹 구조를 위한 효율적 툴의 집합으로 만들었다.

 

2012년 2월 아파치 2.4.x 버전이 공개되었다. 아파치 최신 버전에는 새로운 멀티프로세싱 코어 모듈과 새로운 프록시 모듈이 추가되었다. 그러나 아직 판단을 하기에는 너무 이르다. 

 

엔진엑스는 동시성, 응답성, SSL, 정적 컨텐츠, 압축과 캐싱, 연결과 요청 조절 그리고 심지어 HTTP 미디어 스트리밍 어플리케이션 레이어(엣지 웹 서버 계층을 위한)에 대한 기능을 제공한다. 또한 맴캐시드/레디스 또는 다른 NoSQL 솔루션과의 통합을 제공한다. 많은 수의 동시 사용자가 접속할 때 퍼포먼스를 위해.

 

A few words about the Windows version of nginx. While nginx works in a Windows environment, the Windows version of nginx is more like a proof-of-concept rather than a fully functional port. There are certain limitations of the nginx and Windows kernel architectures that do not interact well at this time. The known issues of the nginx version for Windows include a much lower number of concurrent connections, decreased performance, no caching and no bandwidth policing.

 

윈도우에서 더 적은 동시 연결, 적은 퍼포먼스, 캐싱과 대역폭 정책이 없다는 이슈가 있다.

 

14.2. Overview of nginx Architecture

전통적 프로세스/스레드 기반의 동시 연결은 메모리 및 CPU 사용에서 매우 비효율적일 수 있다. 분리된 프로세스나 스레드를 생성하는 것은 새로운 런타임 환경의 준비를 요구한다. 힙과 스택 메모리 할당을 포함하여 CPU 시간도 들어가며 과도한 쓰레드 컨텍스트 스위칭으로 인해 낮은 성능을 보여준다.

 

서버 리소스의 사용과 일반적으로 적용 가능한 기능과의 tradeoff인 것이다. 동적으로 성장하는 웹사이트에서 상업적 사용과 더 높은 퍼포먼스를 위해 nginx가 사용될 운명이었다. 모듈러, 이벤트 드리븐, 비동기, 싱글 쓰레드, 논브로킹 아키텍처가 엔진엑스 코드의 근간이 되었다.

 

엔진엑스는 멀티플렉싱과 이벤트 알림을 많이 사용한다. 분리된 프로세스에게 구체적인 업무를 할당하며, 매우 효율적인 루프안에서 처리된다. 제한된 수의 싱글 쓰레드인 프로세스(worker), 각 워커에서 엔진엑스는 수천 명의 동시 커넥션과 요청을 처리한다. 

 

Code Structure

엔진엑스의 핵심은 타이트한 런 루프를 유지하고 각 요청 단계에서 적절한 모듈 구성을 실행하는 것이다. 모듈은 대부분의 프레젠테이션과 어플리케이션 레이어 기능을 구성한다. 네트워크와 저장소에 읽고 쓴며, 컨텐츠를 변형하며, 필터링 아웃바운딩, 서버 사이드 작업을 적용한다. (프록싱이 켜졌을 때 요청을 업스트림 서버에 넘기는 것을 포함하여)

 

연관된 액션, 응답, 프로세싱 그리고 네트워크 연결 관리, 엔진엑스는 이벤트 알림 메카니즘과 다양한 디스크 IO 향상(리눅스, 솔라리, BSD 기반 OS)을 사용한다. kqueue, epoll 그리고 event ports

 

목표는 OS에 가능한 많은 힌트를 제공하는 것이다. 인바운드와 아웃바운드 트래픽, 디스크 처리, 소켓에 읽고 쓰는 것, 타임아웃 등을 위한 비동기적 피드백을 적시에 얻는 것과 관련하여 멀티플렉싱을 위한 다른 메소드의 사용과 향상된 IO처리는 주로 모든 Unix 기반 OS에서 향상되었다.

 

Worker Model

엔진엑스는 새로운 프로세스나 쓰레드를 매 연결에 생성하지 않는다. 대신 워커 프로세스는 새로운 요청을 공유된 리슨 소켓을 통해 받아들이고 각 워커 내에서 매우 효율적인 runloop를 처리한다. 워커는 지속적으로 소켓에 읽고 쓴다. (http 요청, 응답을 처리하면서) 런 루프는 포괄적인 내부 콜과 비동기적 task 핸들링에 의존한다. 비동기 처리는 모듈성, 이벤트 응답, 콜백 함수의 광범위한 사용, fine-tuned timers에 의해 구현된다. 전체적으로 핵심 원칙은 가능한한 논 블러킹이 되도록 하는 것이다. 엔진엑스가 블럭킹을 할 수 있는 유일한 상황은 디스크 저장소 성능이 충분하지 않을 때이다. for a woker process.

 

왜냐하면 엔진엑스는 프로세스나 쓰레드를 fork하지 않기 때문이다. 대부분의 상황에서 메모리 사용은 매우 보수적이며 효율적으로 동작한다. 엔진엑스는 CPU 사이클 또한 보수적으로 처리한다. 프로세스나 쓰레드를 처리하는 생성-삭제 패턴이 사용되지 않기 때문이다. 엔진엑스가 하는 것은 네트워크와 저장소를 확인하는 것이다. 새로운 연결을 초기화하고 runloop에 추가한다. 그리고 비동기적으로 실행시킨다. 

 

엔진엑스는 극단적인 workload 상황에서도 중간 수준의 CPU 사용을 달성한다. syscalls의 주의적 사용과 pool와 slab 메모리 할당과 같은 인터페이스를 구현했기 때문이다. 엔진엑스는 여러 workers를 사용하여 커넥션을 다룬다. 코어마다 분리된 워커는 멀티코어 아키텍처의 완전한 활용을 허용한다. 리소스 부족은 존재하지 않는다. 리소스 제어 메카니즘은 싱글 쓰레드인 워커 프로세스내에서 독립적으로 실행된다. 이러한 모델은 물리적 저장 장치 전반에 거쳐 더 확장적이며 디스크 활용도를 높이고 디스크 IO 차단을 방지한다. 

 

결과적으로 여러 작업자들이 작업을 공유하여 더욱 효율적으로 서버 리소스가 활용된다. 로드 패턴이 CPU에 의존적인 경우(TCP/IP 핸들링, SSL, 압축) 일반적인 권장사항은 CPU 코어와 워커 수를 맞추는 것이다. 로드가 주로 디스크 IO에 바인딩된 경우(저장소에서 다양한 컨텐츠를 제공하는 경우, 높은 프록싱) 워커의 수는 1.5에서 2배일 수 있다. 

 

만약 특정 worker에서 디스크 연산을 처리할 정도의 충분한 저장소 성능이 나오지 않는다면, worker는 disk 읽기/쓰기를 차단할 수 있다. 다양한 메카니즘과 구성 파일들은 디스크 IO 블러킹 시나리오를 완하 시킬 수 있다. 특히 sendfile과 AIO같은 조합은 디스크 성능을 위한 많은 여유 공간을 생성한다. 엔진엑스의 설치는 데이터 셋과 엔진엑스가 사용가능한 메모리에 기반하여 이루어져야 한다. 그리고 내부 스토리지의 아키텍처에 기반하여.

 

https://aosabook.org/en/v2/nginx.html

'프로그래밍 > Web Basic' 카테고리의 다른 글

[Express] express 공식 문서 정리  (0) 2023.12.05
Nginx 웹서버 정리 3  (0) 2023.11.17
Nginx 웹서버 정리 1  (0) 2023.11.17
Apache 웹서버 정리  (1) 2023.11.12
클라이언트와 DB 직접 연결하면 안 되는 이유  (0) 2023.11.11

댓글