알고리즘

NginX를 왜 사용하는가?

쿠키담임선생님 2024. 10. 26. 15:17

엔진엑스를 왜 사용할까?

 

웹 서버로 사용하는것은 알고 있는데

 

일단 프론트서버는 web서버로 배포하고

백엔드 서버는 was서버로 배포하면서

 

동적 데이터 처리를 was에 맡긴다.

 

원래는 web서버에서 처리를 했었는데, 너무 부하가 많이 걸려서 동적데이터 처리는 was에서 하는 것으로 변경 되었음.

 

아파치를 사용하면 되는데 왜 엔진엑스를 사용하는 것이고 Web 서버의 역할과 WAS서버의 역할은 무엇인가?


아파치의 구조 때문이다.

 

아파치에서는 요청이 들어오면 커넥션을 생성하기 위해 프로세스를 생성한다. 즉 요청이 들어올 때마다 프로세스가 생성.

하지만 프로세스 생성작업이 오래걸리기에 미리 프로세스를 만들어둔 prefork 방식 사용.

미리 만들어둔 프로세스 다 사용 시 추가로 프로세스 할당.

 

하지만 문제가 발생.

 

동시 커넥션 수가 10000단위를 넘어가니 커넥션 형성이 안된다.

 

이를 해결하기 위해 NginX가 탄생했다.

 

엔진엑스의 구조

  • Master Process
    • 설정 파일을 읽고, 설정 파일에 맞게 worker process생성.
  • Worker Process
    • 실제로 요청을 처리하는 작업.
    • master에서 배정받은 listen socket을 통해 클라이언트와 커넥션 형성. (해당 커넥션은 keep-alive시간만큼 유지된다.)
    • 워커 프로세스에 작업이 들어온다면 해당 요청들을 처리한다. (이러한 커넥션 처리 작업들을 "이벤트"라고 한다.)
    • 이 이벤트들은 OS커널이 큐 형식으로 worker process에게 전달해준다. 큐에 담긴 상태에서 worker process가 처리할 때까지 비동기 방식으로 대기한다.
    • 위 방식의 장점은 요청이 없을 시 방치되던 프로세스를 효율적으로 사용할 수 있다.
    • 그래서 worker process에서 특정 작업이 오래 걸린 경우 쓰레드 풀에 작업을 위임하고 그 시간에 다른 요청들을 처리한다.

 

worker process는 cpu의 코어 갯수만큼 생성.
그 이유는 코어가 담당하는 프로세스를 바꾸는 횟수를 줄일 수 있다.
이렇게 하면 cpu가 부가적인 작업을 하지 않아도 되니 cpu의 context-switching 사용을 줄일 수 있다.

 

 

 

엔진엑스는 리버스프록시 제공, 로드밸런싱 기능 제공, ssl터미네이션 기능제공.

 

여기서 갑자기 궁금한점....

 

aws 도 자체적으로 로드 밸런싱 기능을 제공하고 nginx도 로드밸런싱 기능을 제공하는데 두 기능의 차이점은 무엇일까?


정답은 두개의 커스터마이징 차이이다.

nginx는 사용자에게 맞게 커스텀이 가능하지만 aws는 정책을 따라가기에 하나하나 커스텀하기는 어렵다.

또한 비용도 nginx는 무료이지만 aws에서 로드밸런싱 기능을 사용하게 되면 가격이 오른다.

 

로드 밸런싱 기능으로 서버 분산 처리가 가능하다.

 

예를 들어 was1 서버 was2서버를 구성했을 때, 한 서버에 너무 부하가 몰리지 않도록 설정할 수 있다.

하지만 이렇게 처리 했을 때 하나의 데이터베이스를 공유한다는 문제가 있다.

하나의 데이터베이스를 사용할 때 동시성 문제가 발생 할 수 있다.

 

그래서 스티키세션을 통해 하나의 클라이언트는 하나의 was서버만 사용하게 하는 방법이나

백엔드 코드에서 트랜젝션 격리 수준을 설정하는 방법이 있다.

 

내가 프로젝트하면서 사용했던 방식은 스티키세션 방식 이였다.

이렇게 하면서 was1이 죽었을 시 was2번으로 붙게 설정해주었다.

 

하지만 이렇게 하면 문제점이 생긴다.


서버가 세션을 가지고 있는데.... 세션데이터가 사라진다는 것이다.

그러면 was1로 로그인한 사용자들은 로그인이 풀리게 된다.

 

이를 해결하기 위한 방법이 있다.


세션에 들어가는 회원 데이터를 redis에 저장하는 것이다.

그러면 세션id를 가지고 있는 클라이언트에서 해당 세션id를 request에 담아 서버로 요청하고, 해당 세션id를 키값으로 하여 redis에서 회원정보를 가져온 이후 crud 처리를 하면 된다.

 

 

하지만 위 방법을 아에 사용하지 않는 방법도 있다.


서버에 세션 정보를 저장한는것(stateful) 이 아니라 클라이언트에서 세션정보를 들고 있는 것이다.(stateless)

 

즉 JWT토큰인증 방식을 이용하면 된다. 그러면 서버는 JWT 토큰을 복호화해서 유저정보를 가져올 수 있고 이걸 인증/인가에 사용할 수 있다.

 

ssl 터미네이션이란 https 검증 요청을 NginX에서 하고 서버와는 NginX와 일반 http 로 응답.

 

'알고리즘' 카테고리의 다른 글

백준 - 그룹단어체커(JAVA)  (0) 2024.10.30
백준 - 달팽이(JAVA) - 1913  (0) 2024.10.28
백준 - 문자열 (JAVA)  (0) 2024.10.24
백준 - 이진수 (JAVA)  (0) 2024.10.23
백준 - 크면서 작은 수 (JAVA)  (1) 2024.10.23