해당 게시글은 본 필자가 프로젝트를 진행하면서 생겼던 의문점과 해당 의문점으로 부터 배운 내용에 대한 것을 정리한 것이다.
때는 G-StartUp 이라는 기업협력 프로젝트를 진행함에 있어서 있었던 일이다. 서버의 부하를 줄인다는 것에 관심이 많았고 Nginx를 통한 로드밸런서를 구현했다.
docker를 통해 동일한 node container를 replica로 두고 nginx 로 로드밸런스를 진행하였다. 그리고 이후 개발자 멘토님에게 이러한 방법이 어떤 것 같냐고 여쭤봤고, 예상 외로 혹평을 들었다.
왜 굳이 Nignx를 사용했나?
docker를 통해서 외부 포트를 동일한 포트로 잡으면 딱히 Nginx가 필요없지 않냐? 부하를 줄이려고하는데 Nginx를 사용함으로써 Nginx가 그 부하를 오롯이 받고 있지않나? 라고 의문을 제기하였다.
왜 동일 Replica를 사용하였나?
monolithic한 개발이 아닌 MSA 형태로 기능 별로 다른 Node Container를 두고 Nginx 로 로드밸런서를 두게되면 더 좋을텐데 동일 Replica로 한 이유가 있나?
위의 질문을 받았을 때 나는 꿀먹은 벙어리가 되었다. Nginx에 대한 깊이있는 이해도가 없었기에 아직 부족함이 많다는 것을 느끼게 되었다. 그래서 Nginx 에 대해서 어떻게 사용하면 좋을지에 대한 공부와 방법론에 대한 부분에 대한 간략한 정리를 하려고 생각하여 게시물을 쓰게 되었다.
이를 이해하기 위해서는 먼저 Reverse Proxy에 대한 개념을 이해해야한다.
역방향 프록시라고 불리는 이 녀석은, 웹서버 앞에 위치해서 클라이언트의 요청을 해당 웹서버로 전달해주는 역할을 한다.
주로 사용하는 목적은 보안, 성능, 안정성 향상을 위해 구현된다고 생각하면 편한다. 조금 더 세부적인 목적을 말하면 아래와 같다.
- 부하 분산
- DDOS와 같은 공격으로 부터 보호 (중개하여)
- 캐싱 기능
- SSL 암호화
보통은 Nginx를 사용하는 주된 이유는 1번과 2번과 같은 경우로 인해서 사용하지않을까하고 필자는 생각한다.
1번과 같은 케이스는 홉을 하나 더 늘려서 Nginx를 만든는 것이 오히려 전달을 해야하는 과정이 하나 더 늘어나기 때문에 오히려 비효율적일 수도 있다. 내부적인 복잡한 로직으로 wait 되는 시간이 길어지는 것이 아닐 때는 부하분산에 대한 의미가 없어질 수도 있다.
2번과 같은 케이스는 규모에 따른 얘기이다. 작은 규모의 어플리케이션을 개발함에 있어서 Nginx를 사용하는 것은 큰 의미가 없다는 얘기이다. 오히려 자원을 더 많이 먹게 될 수도 있다. 확장에 대한 잠재성이 클 경우에는 얘기가 달라질 수도 있다.
3번과 같은 케이스의 경우에는 병목에 대한 얘기인데, 요청에 따른 병목지점을 넓히기 위해서 Nginx를 가용하고, Single-Thread 기반인 express에 병목 발생을 막기 위해 Replica를 구성했다. 그런데 단일 데이터베이스를 사용하게 되면 오히려 database 쪽이 병목지점이 될 수 있기에 이런 경우를 잘 고려해야한다.
위와 같은 경우로 인해서 side-effect에 대한 부분을 충분히 이해하고 로드밸런서에 대한 부분을 고려해야한다.
요청에 따른 병목지점을 극복한다는 것이 의미있는 행동인지 고려. 만약에 이를 통해서 요청량이 증가했을 때 받을 수 있다고 한들 데이터베이스와 같은 요소에서 병목이 발생할 수 있다.
홉이 하나 추가 된다는 것을 고려해도 좋은 선택인가?
Nginx 의 목적성이 분명한가?
캐싱, 설정에 대한 부분을 Nginx에서 하고 서버에서는 단순 서비스로직만 구현한다는 등의 Nginx의 분명한 목적성을 가져야한다는 것임.
해당 서비스의 트래픽 상태가 어떠한가?
배포할 때 무중단 배포가 되어야한가?
이러한 간단한 부분을 고려했을 때, trade-off에 대한 것을 생각하여 괜찮다면 가용하면 된다고 생각된다.