[Nginx] Nginx 이해하기
문제 동시 접속자 폭발
네트워크 소켓을 통해 최대로 커버 가능한 동시 접속자의 작업수는 1만개였다. 이때 당시는 사용자 수 = 프로세스 개수(혹은 쓰레드 개수)로 서버 인프라가 설계되어 CPU, 메모리 등 자원들이 사용되었다.
해결 동시 접속에 특화된 Nginx를 쓰자!
효율적인 서버 자원(CPU, 메모리 등) 사용
1. Nginx 개요
세계에서 가장 많이 사용하고 있는 웹서버이다. (웹서버의 TOP2 아파치와 엔진엑스)
동시접속 처리에 특화된 웹 서버로, 가벼움과 높은 성능을 지향하고 있다.
Nginx는 요청에 응답하기 위해 비동기 이벤트 기반 구조이며 이는 Apache 서버의 스레드/프로세스 기반 구조와 대조적이다.
Nginx의 이벤트 기반(Event-Driven) 구조는 서버에 많은 부하가 생길 경우 성능을 예측하기 쉽게 해주며, 고정된 프로세스만 생성하고, 내부에서 비동기방식으로 작업들을 처리하기 때문에 스레드/프로세스를 효율적으로 처리할 수 있다.
* 웹 서버의 역할
1. 정적 파일을 처리하는 HTTP 서버
- 클라이언트가 정적 파일(HTTP, CSS, Javascript, 이미지)만 요청했다면 웹 서버가 직접 응답할 수 있다.
2. 응용프로그램 서버에 요청을 보내는 리버스 프록시
- 프록시는, 클라이언트와 서버 통신 중간에서 대신 통신을 해주는 서버를 의미한다.
- 포워드 프록시는, 내부망에 함께 있는 클라이언트가 인터넷을 통해 어딘가에 있는 서버로 요청을 보내려고 하면 이 요청을 받아 연결해준다. 클라이언트 앞단에서 처리!
- 리버스 프록시는, 내부망의 서버 앞단에서 요청을 배분하여 처리한다. 클라이언트가 리버스 프록시에 요청하면 프록시 서버가 배후 서버(reverse server, 응용 프로그램 서버)로부터 데이터를 가지고 온다. (nginx.conf 파일에서 location 지시어를 사용하여 요청을 배분한다.)
- WAS(Web Application Server)는 대부분 DB 서버와 연결되어 있으므로, WAS가 직접 통신하게 되면 보안에 취약해진다. 리버스
Apache와 Nginx 차이?
과거 멀티 쓰레드를 사용하던 시절엔 Blocking I/O 방식으로 처리가 이루어진다. (*멀티 쓰레드: 하나의 프로그램에 동시에 여러 작업을 돌리는 작업으로, 프로세스 하나의 자원을 공유하다보니 처리 속도가 빠르다는 장점이 있지만, 한정된 프로세스 자원을 쪼개서 사용하는 만큼 쓰레드별로 자원을 효율적으로 분배해야 한다.)
동시 다발적으로 오는 작업에 부적합했다. 요청에 따라 쓰레드/프로세스를 생성하다보니 요청이 많아지거나 오랜 시간이 소요되는 작업에도 처리 방식이 무거워졌다.
그래서 나온 방법 => Non-Blocking !
Non-Blocking 방식은 앞의 프로세스가 작업을 수행중이더라도, 다음 프로세스는 기다리면서 다른 작업을 할 수 있다.
Nginx는 Non-Blocking 방식을 사용하고 있다.
이에 따라 Apache와 Nginx의 차이점을 살펴볼 수 있다.
1) Apache
1995년부터 웹서버 기반 서버엔진.
Prefork와 Worker 방식으로 동작한다.
하나의 요청 당 서버에서는 하나의 프로세스(혹은 쓰레드)를 다룬다. 하지만 서버 내 CPU/메모리는 한정적임에 반해 프로세스(쓰레드)는 요청이 들어온 만큼 계속 생성/작업을 해 무리한 작업이 될 수 있다.
Process가 Blocking시, 프로세스 작업이 끝날 때까지 대기해야 한다.
주로 요청 하나당 프로세스(혹은 쓰레드) 하나가 쓰인다.
자원(CPU, 메모리 등) 사용이 유동적이다. (요청에 따라 쓰레드, 프로세스 할당 개수가 증감된다.)
서버내 자원(CPU, 메모리 등) 활용이 비효율적이다.
2) Nginx
2007년 오픈소스로 공개
프로세스를 효율적으로 활용함으로서 서버 자원을 최대한 활용하고, Event Driven을 활용한 비동기 Non-Blocking 방식을 선호하여 프로세스 작업이 끝날 때까지 대기하지 않아도 된다.
서버가 실행되면 쓰레드를 미리 생성한다. 클라이언트로부터 요청이들어오면 서버에서는 한정된 쓰레드 개수를 기반으로 요청을 처리한다. 하지만 요청이 더 많아질 경우, 늦게 들어온 요청은 잠시 큐에 대기를 하고 작업이 끝난 쓰레드는 큐에 대기하고 있는 요청을 처리한다.
2. Nginx 작동 과정
1. 쓰레드 개수(Thread Pool) 해당 스레드 풀 내에 한정된 자원만을 가지고 HTTP 요청에 대한 작업을 처리한다.
2. 요청에 대한 응답은 Nginx 내부에서 실행되고 있는 Worker Process에서 진행된다. Worker Process는 개발자가 따로 설정하지 않았다면 CPU에 맞게 자동으로 Worker Process가 생성된다.
3. Nginx는 Event Driven(비동기 처리방식)의 특성을 가지고 있다. Event Driven은 Event Loop 기반으로 요청에 대한 작업을 처리한다. (Event Loop에서 작업이 처리될 때, 비동기 방식으로 작업이 돌아간다.)
Nginx Event Driven 내에서 Event Handler에서 작업을 마치게 되면 완료된 순서대로 Queue에 쌒이고 Event Loop를 돌면서 Queue에 완료된 작업이 있는지 체크하면서 CPU가 IDLE한 상태가 없도록 활동한다. Queue에 완료된 작업이 있다면 클라이언트에 응답(Response)한다.
4. Queue에 있는 완료된 작업을 받아 클라이언트에 응답(Response)한다.
출처
https://kbs4674.tistory.com/126
https://whatisthenext.tistory.com/123
'programming language > Dev' 카테고리의 다른 글
[MySQL] SSH 이용해서 sql파일 import 또는 export 하기 / Import and Export (*.sql file) via SSH (0) | 2022.01.25 |
---|---|
[MySQL] MySQL Workbench에서 Table DDL create 스크립트 확인 / How to get a table creation script in MySQL Workbench? (0) | 2022.01.07 |
[python] 파이썬 스케쥴 수행 - python schedule, apscheduler (0) | 2021.12.17 |
[Java] jenv를 활용하여 버전별 JDK 사용하기 (0) | 2021.12.02 |
[Java] JDK 제거하는 법 (0) | 2020.09.29 |
댓글 개