일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 백준
- Real MySQL
- mysql
- SpringBoot
- 스프링
- 자바
- GC
- Stack
- JPA
- gradle
- IntellJ
- redis
- 스트림
- 토비의 스프링 정리
- jvm
- MSA
- Stream
- Collection
- K8s
- list
- thread
- spring
- 보조스트림
- Kotlin
- OS
- 쿠버네티스
- 이스티오
- 자바 ORM 표준 JPA 프로그래밍
- 토비의 스프링
- Java
- Today
- Total
인생을 코딩하다.
[Network] Apache MPM vs Nginx 본문
Apache와 Nginx는 현재까지 가장 폭넓게 쓰이는 2가지의 오픈소스 웹 서버이다.
Apache
Apache는 Client 요청을 받으면 MPM(Multi Processing Module : 다중처리모듈)이라는 방식으로 요청을 처리하며 대표적으로 Prefork와 Work방식이 있다.
MPM
서버는 시스템의 네트워크 포트에 연결하고, 요청을 받아들이며, 받아들인 요청을 처리하기 위해 자식들에게 분배하는 다중처리 모둘(Multi-Processing Modules, MPMs)을 선택할 수 있다. 클라이언트에서 요청을 받으면 MPM 방식으로 처리를 하는데 대표적으로 Prefork와 Worker방식이 있다.
- 커넥션 생성(binding, acecept)
- 커넥션 분배 프로세스든 스레드든 해당 커넥션에 대한 요청을 담당 -> 프로세스든 스레드든 해당 커넥션에 대한 요청을 담당
MPM 모듈 종류(UNIX 계열)
Prefork MPM -> 프로세스가 요청들을 담당해준다.
- 상위 프로세스가 시작되고, 하위 프로세스가 생성된다. 서버는 들어오는 요청을 처리하기 위해 몇 개의 생성된 자식을 계속 실행한다.
- 요청량이 많아질수록 프로세스를 복제하여 동작한다.
- 각 프로세스는 한 번에 한 연결만 처리하고 요청량이 많아 질수록 프로세스는 증가하지만 복제시 메모리영영까지 복제되어 동작하므로 프로세스간 메모리 공유가 없어 안정적이라 볼 수 있다.
- 즉, 단일 스레드 로직에서 작동하며 각 서버 프로세스는 한 번의 하나의 웹 요청을 처리한다.
- 하지만 프로세스를 복제하는 방식이기 때문에 메모리가 많이 소비된다. connection 수 = 프로세스 수 라고 보면 됨
Worker MPM -> 스레드가 요청을 담당해준다.
- Prefork는 한 개의 프로세스가 한개의 스레드로 처리가 되는 동작방식이다. 그에 비해 Worker 방식은 한 개의 프로세스가 여러 쓰레드를 사용하여 요청을 처리한다.
- 쓰레드를 사용하기 때문에 쓰레드간의 메모리를 공유하며 Prefork 방식보다 메모리 소모가 적다.
- 즉, 동시에 여러 스레드를 지원하고 이것은 Apache가 좀 더 효율적이고 확장가능하도록 돕는다.
- 통신량이 많을때 유리하다.
그런데 이렇게 쓰레드나 프로세스를 여러개 만들게 되면 단점이 있다. 만약 10000개의 연결이 동시에 처리가 된다면?
- 메모리...프로세스당 1MB가 필요하다면.. -> 10000 * MB == 10GB!
- 컨텍스트 스위칭 (누구를 실행해야 하지?) -> 4코어면.. 잘 분배되도 2500개?, 컨텍스트 스위칭 오버헤드 * 2500
O(n) // n은 요청수에 비례, 요청이 커지면 문제가 생길 수 있다.
동시에 처리되야 할 숫자에 영향을 받지 않으려면? O(n) -> O(1)이되면 된다.
이 단점을 Nginx가 보완해준다..허나 단점도 존재한다.
Nginx
Nginx 는 Event-Driven 방식으로 동작한다. 한 개 또는 고정된 프로세스만 생성 하고, 그 프로세스 내부에서 비동기 방식으로 효율적으로 작업을 처리한다. 따라서 동시 접속 요청이 많아도 Process 또는 Thread 생성 비용이 존재하지 않는다.
- 웹서버라는 역할에 최적화
- 비동기 방식에 적합한 입력들 (CPU 점유를 적게하는)
- Module로 구성
- Non-blocking
- Single-threaded(worker 프로세스)
* Event-Driven 방식은 작업을 하다 I/O, socket read/write 등 CPU가 관여하지 않는 작업이 시작되면 기다리지 않고 바로 다른 작업을 수행한다. 그러다 진행중인 I/O 등의 작업들이 끝나면 이벤트가 발생하여 그 다음 작업을 처리하게 된다.
중점적으로 봐야 할 부분은 새로운 요청이 들어오면 NGINX의 Worker 프로세스 내부 listener가 요청을 받아 전달한다는 점이다. 각 Worker 프로세스는 내부에서 효율적으로 처리한다. Worker 프로세스는 HTTP 요청과 응답을 처리하는 동안 계속해서 listener를 통해 요청을 받고, 읽고, 쓰기를 반복한다. 각 커넥션마다 프로세스와 쓰레드는 복제(fork)하지 않는다. 따라서 부하가 증가하더라도 CPU/메모리 사용량이 크게 증가하지 않는다.
좀더 간단한 그림으로 동작과정을 말하자면,
1. Reactor는 event가 들어오면 알맞는 handler로 dispatch를 해준다.
2. Handler는 이 dispatch된 event를 받아서 처리하는 역할을 수행
* Reactor : Reacator는 별도의 스레드에서 실행되며 발생한 I/O 이벤트는 dispatching되어 해당 이벤트 처리기로 보내 처리한다.
* Handlers : Reactor로부터 I/O 이벤트를 받아 실제 작업을 수행한다.
Event-Driven 방식은 Reactor pattern을 사용한다고 한다. 간단하게 요약해보자면,
Reactor 패턴은 하나 이상의 클라이언트로 부터의 요청(입력)을 동시처리하기 위해서 사용하는 패턴이다. 서버는 각 입력에 대해서 받을 이벤트를 동적으로 등록/해제하는 식으로 처리해야할 입력과 이벤트를 관리할 수 있다.
- 새로운 연결이 들어온다.
- 이 연결과 연결에 대해서 처리할 이벤트를 일괄 등록한다.
- 이벤트는 "입력 데이터", "출력 데이터", "종료"등이 있을 수 있다.
- 주기적으로 이벤트를 확인한다.
- 이벤트가 발생하면 dispatcher 에 전달해서 처리한다.
- 2번이 multiplexing과정이다. 즉 여러 개의 입력을 처리할 수 있도록 다중화 한다. 3번 과정이 demultiplexing 과정으로 이벤트가 발생한 "하나의" 입력을 찾아낸다.
- 마지막으로 dispacher이 데이터를 처리한다.기본적으로 demultiplexing 에서 multiplexing의 과정이 단일 스레드에서의 처리에 적합한 관게로 단일 프로세스 프로그램에서 두 개 이상의 입력을 처리하기 위해서 주로 사용한다.
Nginx를 사용하기 좋은 예는
로드밸런싱
- 효율성
- 안정성 ( 누군가 죽어도 다른애가 있다.)
리버스 프록시
- 보안
- 유연성 ( 외부에서 직접적으로 모르기에)
레이턴시 감소 ( 앞단에 웹서버 역할을 해주는 애가 대신해주면 자신이 할 일에 집중할 수 있다.)
- 압축
- SSL(암호화)
- 캐시
정리 :
Apache
- 클라이언트 요청을 처리하기 위해 멀티스레드 방식을 따름
- 웹 서버 자체 내에서 동적 컨텐츠를 처리
- 모듈을 동적으로 및 언로드 ( 더 유연하게 만들기)
그러나 웹 트래픽이 많아지면 여러 요청을 동시에 처리 할 수 없다. 클라이언트 요청을 처라하기 위한 다중 스레드 접근 방식을 따르고 스레드는 한 번에 하나의 연결만 처리 할 수 있기 때문.
Nginx
- 이벤트 중심 접근 방식을 사용하여 클라이언트 요청 제공
- 제한된 하드웨어 리소스로도 여러 클라이언트 요청을 동시에 효울적으로 처리
- 단일 스레드를 통해 여러 연결을 처리할 수 있음
- 최소한의 리소스로 웹 서버의 아키텍처를 개선하기 위해 독립형 HTTP 서버로 배치 가능
하지만 동적 컨텐츠를 기본으로 처리 할 수 없다. 동적 컨턴체에 대한 기타 요청을 처리하려면 이를 실행하기 위해 외부 프로세서로 전달하고 렌더링 된 콘첸츠가 다시 전송 될 때까지 기다려야한다. 즉, 프로세스 속도 저하
출처 :
old.zope.org/Members/ike/Apache2/osx/configure_html
www.joinc.co.kr/w/Site/SoftWare_engineering/pattern/reactor
taetaetae.github.io/2018/06/27/apache-vs-nginx/
webinstory.tistory.com/entry/Apache-vs-Nginx-%EB%B9%84%EA%B5%90
blog.naver.com/PostView.nhn?blogId=tmondev&logNo=220737182315
'Network' 카테고리의 다른 글
[Network] 서비스의 보안을 위해 어떻게 CIA를 지킬 수 있을까?(2) - RSA로 해결 (0) | 2022.02.20 |
---|---|
[Network] 서비스의 보안을 위해 어떻게 CIA를 지킬 수 있을까? (0) | 2022.02.10 |
[Spring] Proxy. Forward Proxy, Reverse Proxy, Load Balancer (0) | 2021.02.13 |
[Network] Web Server vs WAS (0) | 2021.02.09 |