가상면접 사례로 배우는 대규모 시스템 설계 기초
12장 채팅시스템 설계
1. 문제의 이해 및 설계범위 확정
- 채팅앱의 종류가 여러가지이기 때문에 면접관과 이에 대해 명확히 기준을 잡아두는 것이 필요하다.
- 1:!일 채팅에 집중하는지, 그룹채팅에 중점을 두는지, 메시지를 주고받는데 중점을 두는지, 음성채팅이 중요한 앱인지....
- 일별 능동 사용자 수가 몇명인가?
- 접속상태를 표시해야하는가? 푸시알림이 필요한가?
- 하나의 계정으로 여러 단말에 동시접속을 지원 해야 하는가?
- 종단간 암호화기능이 필요한가?
일별 능동 사용자 수(DAU: Daily Active User)
- 앱을 다운로드하고 사용한 사람. 업종별로 '사용'의 기준이 다르다. 우리도 단순 로그인 기준으로 해야할지, 채팅을 확인하거나 보내는 것을 기준으로 해야할 지 논의가 필요할 수 도 있다.
종단간 암호화
- 메시지의 발신원, 수신원의 정보를 암호화 한채로 전송하는 방식.
- 종단간 암호화가 방식이 아닌 경우 발신원에서 정보를 암호화 하였다가 서버에서 복호화 했다가 다시 재 암호화를 해서 수신원으로 전달한다.
- 종단간 암호화 방식은 발신원에서 수신원으로 전송 될 때 정보가 암호화 된 채 복호화를 거치지 않고 그대로 전달된다.
- 예를들면 텔레그램, 카톡 비밀채팅기능 등에 사용 된다.
2. 개략적 설계안 제시
- 프로토콜은 대개 HTTP를 사용한다. 클라이언트와 서버 사이의 연결을 끊지 않기 위해서 keep-alive 헤더를 사용하는데, 핸드셰이크 횟수를 줄일 수 있어서 좋다.
- 서버에서 클라이언트로 메시지를 보내는데 쓰이는 프로토콜은 폴링방식, 롱폴링방식, 웹소켓 방식이 있다.
핸드셰이크
- 기기간에 서버가 연결되어있는지 확인하는 과정이다.
- 필요한 기능이지만, 불필요한 통신이 발생할 수 있어 효율적으로 사용 할 수 있어야한다.
2-1. 폴링방식
- 클라이언트가 주기적으로 서버에게 메시지가 있는지 물어보는 방식.
- 서버자원의 불필요한 낭비 발생
2-2. 롱폴링 방식
- 폴링방식을 보완하고자 나온 방식
- 클라이언트가 서버에게 메시지가 있는지 물어본 뒤에, 새 메시지가 반환되거나 타임아웃될 때까지 서버연결을 계속 유지하는 방식.
- 새 메시지를 받으면 하나의 연결이 종료되고 새 연결이 생성됨.
- 메시지를 HTTP 서버를 사용할 경우 무상태 서버이기 떄문에, 메시지를 보내는 클라이언트와 수신하는 클라이언트의 서버가 달라질 수 있다. 결국, 대화가 이어지지 않을 수도 있다는 것.
- 서버 입장에서는 클라이언트가 연결을 해제 했는지 알 방법이 없다.
- 여전히 비효율적
무상태 서버(stateless)
- 이전의 클라이언트 상태 및 요청을 전혀 기억하지 못함.
- 프로필확인, 로그인확인과 같은 단발성 데이터 전송에 사용됨.
- 채팅기능에 적합하지 않을 뿐.
라운드로빈
- 로드밸런싱을 위해 사용되는 알고리즘방식
- 클라이언트의 요청을 서버에 순차할당하는 방식이다.
2-3. 웹소켓
- 클라이언트가 서버에 연결을 요청할 때, 한번 맺어진 연결이 항구적이며 양방향이다.
- 방화벽이 있는 환경에서도 잘 동작함.
- 양방향 메시지 전송까지 가능하게 하기 때문에 HTTP방식을 굳이 고집할 필요 없이 웹소켓을 쓰면 된다.
- 항구적 연결이기 떄문에 서버에서 연결관리를 효율적으로 해야함
설계안
- 채팅앱의 부분은 무상태 서비스가 가능한 부분/ 상태유지를 해야하는 부분/ 제3자 서비스를 연동해야하는 부분으로 나뉜다. 무상태 서비스가 가능한 부분은 http로, 상태유지가 필요한 부분은 웹소캣으로, 제 3자 서비스를 연동해야 하는 부분은 제 3장을 참고하도록 한다.
규모 확장성
- 이론적으로는 서버 한개로 설계 해도 서비스 이용에 문제가 없지만, SPOF 측면에서 봤을 때 별로 좋은 답변이 아니다.
- 채팅서버, 접속상태서버, API 서버, 키값저장소로 나눔
SPOF(Single Point Failure)
- 단일장애점. 동작하지 않으면 전체시스템이 중단되는 요소
3. 생각해볼점
- 종단 간 암호화의 필요성과 설계방식