Today I Learned
(24.10.17) NginX 정리 + 본인 프로젝트에서 활용한 부분 추가
실제 프로젝트에서 NginX를 활용해서 일종의 리버스 프록시 서버로 React 컨테이너와 Spring Boot 가 실행되는 컨테이너 사이에서
사용자 화면단에서 작동될 수 있도록 활용을 했다.
하지만, NginX를 사용한 이유, 그리고 어떻게 구체적으로 작동하는지에 대해서 더 자세하게 찾아보고
프로젝트 구성과 데이터 흐름을 더욱 이해하려고 했고 이를 정리했다.
NginX
- 고성능 웹 서버, 리버스 프록시 서버
- Web Application 단에서 요청을 처리, 정적 콘텐츠를 제공하는 웹서버 역할
아키텍쳐 및 구조
- 비동기 이벤트 기반의 아키텍처
- 고성능의 동시 연결 처리 기능
- 단일 쓰레드에서 여러 요청을 동시에 처리하는 방식
- 메모리 사용량을 줄이고 성능을 향상
Process 구조
- Master Process
- NginX 설정 파일을 읽고, Worker Process를 생성
- nginx.conf 설정파일
- /etc/nginx/nginx.conf 경로에 위치
http { server { listen 80; # HTTP 포트 server_name example.com; # 서버 이름 location / { root /var/www/html; # 정적 파일 경로 index index.html; # 기본 인덱스 파일 } location /api { proxy_pass <http://localhost:8080>; # 백엔드 API 서버로 프록시 } } }
- nginx.conf 설정파일
- 수정, 변경사항이 있을 경우에도 다시 Worker Process 생성
- 일반적으로 nginx 설정에 따라 CPU 코어 수만큼 Worker Process 생성하여 Context Switching 최소화, 성능 최적화 가능
- NginX 설정 파일을 읽고, Worker Process를 생성
- Worker Process
- 요청을 실제로 처리하는 Process
- 여러 개의 Worker Process가 동시 처리
- Worker Process는 단일 쓰레드 이기 때문에 Master Process에서 코어 수에 맞춰서 미리 Worker Process 작동 갯수를 정해놨음(위 참고)
- 비동기 기반으로 클라이언트 요청처리
- 스케쥴링으로 순차적으로 처리가 시작이 되나, 처리가 완료된 시점은 이벤트 큐의 순서와 상관 없음
- 여러 개의 Worker Process가 동시 처리
- Listen Socket을 통해 요청 수신
- 요청을 실제로 처리하는 Process
Listen Socket
- 각 Worker Process는 자신이 배정받은 Listen Socket을 통해 클라이언트의 요청이 전달,처리
- 연결(Connection)이 유지되는 동안 여러 요청을 처리
- Keep-Alive 설정 시간 만큼 Connection 유지
- 요청이 없을 경우, 다른 연결을 처리를 위한 비동기 방식으로 전환
Nginx 요청 처리 FLOW
- 클라이언트의 요청 수신
- 클라이언트가 웹 서버로 요청
- Nginx는 해당 요청을 Listen Socket을 통해 수신
- 이벤트 처리 (Event-Driven Model)
- 이벤트(Event) :
- 비동기 기반 처리
- 요청에 따른 연결(Connection) 수신, 형성, 처리, 종료, 새로운 요청처리 와 같은 모든 작업
- 프로젝트에서의 과정 : Event 처리 중 필요한 정적 리소스를 NginX 는 React에게 요청
- **OS 커널(Nginx가 실행되는 OS)**이 이벤트를 Queue에 담아 Nginx의 Worker Process에게 전달
- Worker Process는 해당 Queue에서 이벤트를 꺼내 처리
- 단일 쓰레드 이기 때문에, 스케쥴링에 맞춰서 돌아가면서 처리, 따라서 순차적으로 처리가 완료가 안될 수 있음
- epoll 메커니즘
- 대기이벤트가 끝나면 큐에 맞춰서 다음 이벤트를 자동으로 진행, 모든 이벤트 처리시 Idle = 대기 상태로 전환
- 리소스 효율적인 사용
- 이벤트(Event) :
- 오래 걸리는 작업 처리 (Thread Pool)
- 작업 시간이 오래 걸릴 경우, Thread Pool을 사용하여 해당 작업을 Worker Process가 아닌 별도의 Thread로 위임하여 처리
- 해당 Thread Pool은 NginX 웹 서버 CPU리소스에 해당하는 Thread Pool
- Worker Process는 대기 중인 다른 이벤트를 처리를 계속해서 진행
- 작업 시간이 오래 걸릴 경우, Thread Pool을 사용하여 해당 작업을 Worker Process가 아닌 별도의 Thread로 위임하여 처리
- 응답 반환
- 요청 처리가 완료되면, Nginx는 클라이언트에게 응답을 반환 (정적 리소스 반환)
- React Application 역시 포함되어서 반환
- 정적 파일을 제공하거나, 리버스 프록시로 백엔드 서버의 응답을 클라이언트에게 전달
- 요청 처리가 완료되면, Nginx는 클라이언트에게 응답을 반환 (정적 리소스 반환)
+(이후 처리)
- API 요청 전송 (React → Nginx → Spring)
- React Application이 Data가 필요로 하게 될 때, API 요청을 NginX를 통해 요청
- 일종의 리버스 프록시 역할
- 데이터 응답역시 JSON 형태로 NginX를 통해 React Application으로 전달
- React Application이 Data가 필요로 하게 될 때, API 요청을 NginX를 통해 요청
- React 애플리케이션에서 데이터 반영 (클라이언트)
- 받았던 React 정적 리소스 + API 응답 데이터를 토대로 브라우저의 콘텐츠를 갱신
주요 기능
웹 서버 Web Server
- HTML, CSS, JavaScript, 이미지 등의 정적 콘텐츠 제공
- 비동기 방식으로 인한 고성능 동시 연결 처리 가능
리버스 프록시 Reverse Proxy 서버
- 여러개의 BE Server 단으로 Client 단의 요청 전달, 응답 반환하는 서버
- 클라이언트는 NginX와만 통신을 진행해도 BE 서버에 직접적인 정보와 처리를 알 수 없음
- Nginx는 추가 서버가 추가되더라도 클라이언트와의 연결을 유지, 이벤트 단위로 요청을 적절히 분배하여 처리
- Load Balancing
- 여러 Server 로 요청을 분산가능
- Round Robin 방식을 기본
- 서버 부하 감소, 고가용성 유지
- 여러 Server 로 요청을 분산가능
- SSL Termination
- SSL/TLS 암호화 통신을 중간에서 해제할 수 있는 과정
- HTTPS 사용 경우
- Client 단과 SSL 종료 후, 이어서 Server 단과 일반 HTTP 통신이 가능
- SSL/TLS 암호화 통신을 중간에서 해제할 수 있는 과정
- URL Rewrite & Redirection
- 클라이언트의 요청 URL을 조건에 따라 변환/리다이렉트
캐싱 Caching
- 정적 콘텐츠 캐싱
- 프록시 캐싱
- BE Server 응답을 캐싱해서 후속 요청시 빠르게 응답하는 역할
장점
- 대용량 동시 연결 처리
- Apache Server 대비 10~1000배
- 빠른 동시 연결 처리
- 프로세스 수 대비 효율적인 처리 : 가볍게 사용 가능
- 이벤트 기반 구조로 인한 속도 증가
- 프로세스 수 대비 효율적인 처리 : 가볍게 사용 가능
- 동적인 설정 변경 가능
- 설정에 따라 Master Proces에 의한 Workder Process 생성 조절 가능
단점
- 어려운 기능 확장
- 서버 모듈(인증, 접근제어, 로그 수집 등), 자체 보안 기능 추가, 캐싱 전략 수정 등의 기능 또는
- 정상 동작 중이 Worker Process가 새로운 기능 추가시 종료될 수 있음
- 이 때, 관련 연결 및 요청 처리가 모두 불가하게됨
- 복잡한 커스텀 모듈
Apach Server 와 비교
Apach Server
- 스레드 기반 또는 프로세스 기반 아키텍처
- 요청 마다 새로운 프로세스 또는 스레드를 생성해서 사용하는 메모리 소모가 큰 구조 → 따라서 대용량 트래픽 처리도 한계
- 동적 모듈을 지원, 필요에 따라 모듈을 로드하고 언로드
- 커스터마이징 및 기능 추가 용이
특징 | Nginx | Apache |
아키텍처 | 비동기 이벤트 기반 | 스레드 또는 프로세스 기반 |
성능 | 높은 동시 연결 처리 정적 콘텐츠 제공에 강점 |
많은 동시 요청 처리 시 성능 저하 가능 |
모듈 구조 | 동적 모듈 미지원, 컴파일 시 포함 필요 | 동적 모듈 지원, 필요 시 로드/언로드 가능 |
설정 파일 | 간결하고 직관적 | 복잡할 수 있으며 이해하기 어려움 |
SSL/TLS 처리 | SSL Termination을 효율적으로 처리 | SSL/TLS 지원하지만 성능 낮을 수 있음 |
용도 | 정적 콘텐츠 제공, 리버스 프록시, 로드 밸런서 | 동적 콘텐츠 처리에 강점, 다양한 웹 애플리케이션 호환성 |
리소스 소모 | 적은 CPU 및 메모리 사용 | 상대적으로 더 많은 리소스 사용 |
'Today I Learned' 카테고리의 다른 글
(24.10.29) Comparator 인터페이스와 람다식 (0) | 2024.10.29 |
---|---|
(24.10.21) Message Queue 그리고 Redis (1) | 2024.10.21 |
(24.10.14) Swagger & Spring REST Doc (2) | 2024.10.14 |
(24.10.10) TDD & DDD / Filter & Interceptor & AOP 비교해보기 (0) | 2024.10.10 |
(24.10.08) 보안 공격 정리 : SQL Injection, CSRF, XSS (0) | 2024.10.08 |