Home [football] Scale Out을 고려한 아키텍처 설계
Post
Cancel

[football] Scale Out을 고려한 아키텍처 설계

# 문제점


애플리케이션이 실제 배포가 되었을 때, 사용자 수가 증가함에 따라 트래픽이 증가할수록 서버를 확장해야 하는데 하나의 서버로만 실행한다면 SPOF로 인해 확장이 불가능해 심각한 장애를 발생시킬 수 있다고 생각했습니다. 그래서 아키텍처 설계 단계에서부터 Scale Out이 가능한 아키텍처 설계를 고민해보고 구성해보기로 결정했습니다.

# 해결방안


1. API 서버와 채팅서버를 분리

사용자 요청을 처리하기 위해 직접 접근해야 하는 API 서버와 웹소켓 연결을 위해 동일하게 사용자의 요청을 처리해야하는 채팅 서버를 분리하고, 두 서버의 역할을 명확하게 구분하는 것과 동시에 서버 확장에도 용이한 구조로 설계했습니다.

2. 웹소켓을 직접 활용한 채팅 기능 구현

채팅기능 구현을 위해서 STOMP를 활용하는 방법을 고려해볼 수도 있지만 다중 웹소켓 서버를 사용하는 환경에서 STOMP를 활용해 메세지를 전송할 때 외부 브로커에게 의존하는 형태로 동작하게 되어 외부 브로커에 많은 요청이 몰려 채널이나 큐가 과하게 추가되면 과부화가 올 수 있다고 판단했습니다.

이를 해결하기 위해 외부 브로커로 사용되는 플랫폼에 클러스터링 기능을 활용해 보는 것도 고려해봤지만, 메세지를 송신받은 클라이언트 입장에서 어느 노드에 어떤 토픽이 저장되어 있는지 알 수 없어 모든 노드가 동일한 토픽에 대해 저장되어야 합니다. 이는 확장성이 완벽하게 보장된 구조라고 보기 힘들다고 판단했습니다.

결국 웹소켓을 통해 직접 채팅 기능을 구현하는 방법을 채택하게 되었습니다.

3. Health Check

채팅 서버의 확장성을 보장하면서 채팅 기능을 구현하려면 API 서버 입장에선 메세지를 받아야 하는 사용자가 접속한 채팅 서버 주소를 알아야 합니다. 그래야 채팅방에 포함된 사용자가 접속한 채팅 서버 주소로 메세지 전송 요청을 보낼 수 있기 때문입니다.

그래서 채팅 서버에서 지속적으로 서버 상태에 대한 데이터를 API 서버에 보내고, API 서버는 채팅 서버의 상태 정보를 저장하도록 Health Check 기능을 구성했습니다.

4. 최적 접속 웹소켓 서버 선정 로직

클라이언트 입장에선 접속할 채팅 서버의 주소를 직접 알지 못할 뿐만 아니라 여러 채팅 서버를 구성하는 구조에선 적절한 분배를 해주지 않으면 특정 채팅 서버에 접속자가 몰려 비효율적인 서버 활용을 할 수 있습니다.

그래서 API 서버가 클라이언트로부터 웹소켓 접속 요청을 받으면 지속적으로 체크하는 Health Check 정보를 가지고 가장 접속자 수가 적고 서버가 현재 살아 있어 서비스 장애를 일으키지 않을 최적의 서버 주소를 리턴해주도록 했습니다.

5. Redis Cluster

채팅 서버에 대한 Health Check 정보를 저장하기 위해서 Redis를 선택했습니다. Redis를 활용하면서 빠른 저장 및 조회를 통해 성능적인 측면에서는 높힐 수 있었지만 하나의 Redis 서버를 사용하는 구조에선 SPOF에 대한 위험이 존재한다고 판단했습니다.

그래서 Redis Cluster 모드를 통해 하나의 서버에 모든 데이터를 저장하지 않고 분산 저장함으로써 데이터 분실에 대한 위험도를 낮출 수 있었습니다. 또한 2번에서 말한 것처럼 STOMP를 활용하는 경우에 외부 브로커의 클러스터링을 활용하는 것보다 현재 구상하는 구조에서 활용하는 Redis Cluster는 데이터 분산처리 및 확장성을 상대적으로 잘 보장된 구조라고 판단되었습니다.

6. 설계된 아키텍처 도안

위에 작성한 문제가 될 수 있는 지점들을 고려해 작성한 아키텍처 도안은 다음과 같습니다.

# 마치며


이처럼 아키텍처 설계 단계에서부터 확장 가능성을 고려해봄으로써 트래픽 과부하, 싱글 서버 다운으로 발생할 수 있는 장애 등의 문제를 해결할 수 있는 최적의 설계를 구현하기 위한 깊은 고민을 해볼 수 있었습니다.

# 참고자료


  • https://brunch.co.kr/@springboot/695
This post is licensed under CC BY 4.0 by the author.

[football] Github Actions를 활용한 CI/CD

[football] 비동기 방식으로 처리되는 메시지 및 푸시알림 전송 로직 구현