요구사항
1. 응답지연이 낮은 일대일 채팅 기능
2. 최대 100명까지 참여할 수 있는 그룹 채팅 기능
3. 사용자의 접속상태 표시 기능
4. 다양한 단말 지원, 하나의 계정으로 여러 단말에 동시 접속 지원
5. 푸시 알림
+) 5천만 DAU 처리할 수 있도록 설계
1차 설계
1. 설계 전 고려사항 : 네트워크 통신 프로토콜 결정
- 메시지 요청 시나리오에서는 HTTP 프로토콜 : keep-alive 헤더 사용해서 클라이언트와 서버 사이의 연결을 유지
ㄴ 페이스북 같은 많은 대중적 채팅 프로그램이 초기에 HTTP를 사용함
- 메시지 수신 시나리오에서는 HTTP 프로토콜을 사용하기에는 서버에서 클라이언트로 임의 시점에 메시지를 보낼 때 사용 못하므로, 이때를 위해 다른 기법을 사용한
ㄴ 폴링(polling), 롱 폴링(long polling), 웹 소켓(websocket)
폴링 | - 클라이언트가 주기적으로 서버에게 새 메시지가 있느냐고 물어보는 방법 - 단점 ㄴ 폴링을 자주하면 비용이 올라간다. ㄴ 답해줄 메시지가 없는 경우에는 서버 자원이 불필요하게 낭비된다. |
|
롱폴링 | - 클라이언트는 새 메시지가 반환되거나 타임아웃될 때까지 연결을 유지하는 방법 - 새 메시지를 받으면 기존 연결을 종료하고 서버에 새로운 요청을 보내어 모든 절차를 다시시작함 - 약점 ㄴ 메시지를 보내는 클라이언트와 수신하는 크라이언트가 같은 채팅 서버에 접속하게 되지 않을 수 있음 ㄴ 서버 입장에서는 클라이언트가 연결을 해제했는지 아닌지 알 좋은 방법이 없다. |
|
웹소켓 | - 서버가 클라이언트에게 비동기 메시지를 보낼 때 가장 널리 사용되는 기술 - 동작원리 ㄴ 클라이언트가 연결을 시작해서 처음에는 http이지만 특정 핸드셰이크 절차 거치면서 웹소켓 연결로 업그레이드됨 |
*웹소켓을 이용하면 메시지를 보낼 때나 받을때나 동일한 프로토콜을 사용할 수 있음
2. 1차 설계
1) 무상태 서비스 : 로그인, 회원가입, 사용자 프로파일 표시 등을 처리하는 서비스
2) 상태 유지 서비스 : 채팅 서비스
3) 제 3자 서비스 연동 : 푸시 알림
2차 설계
1. 설계 전 고려사항 : 규모 확장성
- 동시 접속자가 1M이라고 가정하면, 접속당 서버 10K의 서버 메모리가 필요한다고 보면
10GB 메모리만 있으면 모든 연결을 처리할 수 있음
- 하지만 서버 한대에 담은 설계안으로는 SPOF의 문제가 발생할 수 있음
2. 설계 전 고려사항 : 저장소
- 채팅 시스템에서 다루는 데이터는 보통 두 가지이다.
ㄴ 사용자 프로파일, 설정, 친구 목록처럼 일반적인 데이터로 -> 관계형 데이터베이스에 보관
ㄴ 채팅 시스템의 고유한 데이터 -> 키-값 저장소
*키-값 저장소의 장점
- 수평적 규모확장이 쉬움
- 데이터 접근 지연시간이 낮음
- 이미 많은 시스템이 키 값 저장소를 채택하고 있음. 페이스북 메신저는 Hbase를, 디스코드는 Cassandra를 이용
3. 2차 설계
- 채팅 서버는 클라이언트 사이에 메시지를 중계하는 역할을 담당한다.
- 접속상태 서버는 사용자의 접속 여부를 관리한다.
- API 서버는 로그인, 회원가입, 프로파일 변경 등 그 외 나머지 전부를 처리한다.
- 알림 서버는 푸시 알림을 보낸다.
- 키-값 저장소에는 채팅 이력을 보관하나. 시스템에 접속한 사용자는 이전 채팅 이력을 전부 보게 될 것이다.
상세 설계
1. 서비스 탐색
- 주된 역할은 클라이언트에게 가장 적합한 채팅 서버를 추천하는 것.
- 널리 쓰이는 오픈 소스 솔루션으로 아파치 주키퍼등이 있음
2. 메시지 흐름
1) 1:1 채팅 메시지 처리 흐름
- 사용자 A가 채팅 서버 1로 메시지 전송
- 채팅 서버1은 ID 생성기 사용해 해당 메시지의 ID 결정
- 채팅 서버1은 해당 메시지를 메시지 동기화 큐로 전송
- 메시지가 키-값 저장소에 보관됨
- 사용자B가 접속 중이면 사용자B가 접속 중인 채팅 서버로 전송, 아니라면 푸시 알림 메시지를 푸시 알림 서버로 보냄
- 채팅 서버2는 메시지를 사용자B에게 전송
2) 여러 단말 사이의 메시지 동기화
- cur_max_message_id : 해당 단말에서 가장 최신의 메시지 id
3) 소규모 그룹 채팅에서의 메시지 흐름
- 새로운 메시지가 왔는지 확인하려면 자기 큐만 보면 되니까 메시지 동기화 플로가 단순하다.
- 그룹이 크지 않으면 메시지를 수신자별로 복사해서 큐에 넣는 작업의 비용이 문제가 되지 않는다.
3. 접속상태 표시
1) 사용자 로그인 : 웹소켓 연결이 맺어지고 나면 last_active_at을 가지고 키-값 저장소에 보관
2) 로그아웃 : 키-값 저장소에 보관된 사용자 상태가 offline으로 변경
4. 접속 장애
- 간단한 방법은 사용자를 오프라인 상태로 표시하고 연결이 복구되면 온라인 상태로 변경하는 것.
ㄴ 짧은 시간동안 인터넷이 끊어졌다 복구되는 일이 흔하기 때문에, 이럴때마다 접속 상태 변경하는 것은 지나침
- 박동 heartbeat 검사를 통해 x초 이내에 또 다시 이벤트 받으면 접속상태를 유지
5. 상태 정보의 전송
- 발행-구독 모델을 사용
ㄴ 가령 사용자 A의 접속상태가 변경되었다고 하면, 그 사실을 A-B, A-C, A-D에 쓰는것.
ㄴ 그룹 크기가 작을 때 효과적이다.
ㄴ 그룹 크기가 크다면, 해소하는 한 가지 방법은 그룹 채팅에 입장하는 순간에만 상태 정보 읽거나 수동으로 상태 정보 갱신하도록 유도하는것.
마무리
1. 채팅 앱을 확장하여 사진이나 비디오 등의 미디어 지원 : 미디어 파일은 텍스트에 비해 크기가 크므로, 압축방식, 클라우드 저장소, 썸네일 생성 등을 이야기해볼 수 있음
2. 종단 간 암호화 : 왓츠앱은 메시지 전송에 있어 종단 간 암호화를 지원
ㄴ https://faq.whatsapp.com/820124435853543/?locale=en_US
3. 캐시 : 클라이언트에 이미 읽은 메시지 캐시해두면 서버와 주고받는 데이터 양 줄일 수 있음
4. 로딩 속도 개선 : 슬랙은 사용자의 데이터, 채널 등을 지역적으로 분산하는 네트워크 구축해 앱 로딩 속도 개선함
5. 오류 처리
- 채팅 서버 오류 : 채팅 서버 하나에 수십만 사용자가 접속해있는데, 하나가 죽으면 서비스 탐색 기능이 동작하여 클라이언트에게 새로운 서버를 배정하고 다시 접속할 수 있도록 해야함
- 메시지 재전송 : 재시도나 큐
'스터디 > [가상면접 사례로 배우는 대규모 시스템 설계 기초] (2024.4)' 카테고리의 다른 글
[가상면접 사례로 배우는 대규모 시스템 설계 기초] Ch10. 알림 시스템 설계 (0) | 2024.05.30 |
---|---|
[가상면접 사례로 배우는 대규모 시스템 설계 기초] Ch7. 분산 시스템을 위한 유일ID 생성기 설계 (0) | 2024.05.04 |