이전에 채팅 시스템에 대해서 위와 같이 WebSocket 방식의 채팅 이면서 메시지는 NoSQL에 저장하는 형태를 고려해봤다.
이제, 중간에 Server를 구체화할 예정이다.
무상태 서비스와 상태유지 서비스 구분짓기
여러 서비스를 제공하는 서버에 대해서 상태에 따른 서비스를 분류할 필요가 있다.
- 무상태서비스: 로그인, 회원가입, 배치, 공통유틸 등 전통적인 요청/응답 서비스 (클라이언트 상태 관리 X)
- 상태유지서비스: 채팅서비스, 즉 클라이언트와 서버가 네트워크 연결을 유지해야 하는 서비스
아래는 이러한 상태에 다른 서비스를 시각화했다.
사용자의 요청에 따라 로드밸런서가 각 서버로 요청을 분산시키는 형태다.
이와 반대로, 상태 유지를 하는 채팅 서비스는 별도로 분리되어 로드밸런서의 영향을 받지 않는다고 치자.
이 상태를 종합하여 단일 유저 기준으로 보자면 다음과 같은 서버 구조가 나올 거다.
필요에 따라서 채팅에 따른 푸쉬알람과 같은 제 3의 서비스를 연계해야 할 수도 있으나 생략한다
또한 Cahtting 서비스는 당연히 나머지 세 서비스와 협력하는 과정이 있겠으나 표시는 생략한다.
더불어서 중점적으로 다룰 Chatting 서비스만 다중화되었다는 표시를 넣었다.
형광칠을 한 건 다음과 같은 흐름을 의미한다.
"사용자는 인증 서버를 통해 JWT 토큰을 반환받는다"
"사용자는 인증된 토큰을 통해 Communication 서버에서 본인이 접속할 ChatServer를 찾는다"
"사용자는 반환된 Chatting 서버로 웹소켓 연결을 진행한다"
그런 과정의 최종 목표는 다음과 같다.
"사용자 B가 메시지를 발행하면 사용자 A는 수신할 수 있어야 한다"
하지만, 사용자 A와 사용자 B가 각각 다른 서버에 연결되어있다면 각 서버는 수신자를 달리 알고 있기에 문제가 될 것이다.
메시지 큐 적용하기
메시지 영역만 따로보자. 간단히 큐 서비스를 연동시키면 서로가 가진 메시지를 동기화 시키고 목적지로 안전하게 보낼 수 있다.
해당 Queue 부분은 그 규모에 따라 채팅방 별로 할 것이냐, 유저별로 생성할 것이냐, 복제할 것이냐 등등의 선택지도 있을테지만 큐는 이전의 단독 포스팅으로 대신한다.
여기까지 정리하면 이러한 구조가 된다
Reference