Skip to main content

12장. 채팅 시스템 설계

  • 아래는 채팅 앱에 대한 설계 문제입니다.
  • 일대일 채팅 앱과 그룹 채팅 앱은 다르므로 요구사항을 확실히 알아야 합니다.

1단계 문제 이해 및 설계 범위 확정#

  • 아래는 요구 사항입니다.
    • 응답지연이 낮은 일대일 채팅 기능
    • 최대 100명까지 참여할 수 있는 그룹 채팅 기능
    • 사용자의 접속상태 표시 기능
    • 다양한 단말 지원, 하나의 계정으로 여러 단말에 동시 접속 지원
    • 푸시 알림
  • 5천만 DAU를 처리할 수 있으면 좋습니다.

2단계 개략적 설계안 제시 및 동의 구하기#

  • 채팅 서비스는 아래 기능을 제공해야 합니다.
    • 클라이언트들로부터 메시지 수신
    • 메시지 수신자(recipient) 결정 및 전달
    • 수신자가 접속(online) 상태가 아닌 경우에는 접속할 때까지 해당 메시지 보관
  • 서버가 연결을 만드는 방법으로 많은 기법이 존재합니다.
    • 폴링, 롱 폴링, 웹소켓

폴링#

  • 폴링은 클라이언트가 주기적으로 서버에게 새 메시지가 있는지 물어보는 방법입니다.
  • 폴링 비용은 폴링을 자주하면 할수록 올라갑니다.

롱 폴링#

  • 폴링은 여러 가지로 비효율적일 수 있어서 나온 기법이 롱 폴링입니다.
  • 롱 폴링의 경우 클라이언트는 새 메시지가 반환되거나 타임아웃 될 때까지 연결을 유지합니다.
  • 아래의 약점이 있습니다.
    • 메시지를 보내는 클라이언트와 수신하는 클라이언트가 같은 채팅 서버에 접속하게 되지 않을 수도 있습니다.
    • 서버 입장에서는 클라이언트가 연결을 해제했는지 아닌지 알 좋은 방법이 없습니다.
    • 여전히 비효율적입니다.

웹소켓#

  • 서버가 클라이언트에게 비동기 메시지를 보낼 때 가장 널리 사용하는 기술입니다.
  • 웹소켓 연결은 클라이언트가 시작합니다. 한번 맺어진 연결은 항구적이며 향방향입니다.
  • 웹소켓을 이용하면 메시지를 보낼 때나 받을 때 동일한 프로토콜을 사용할 수 있으므로 설계뿐만 아니라 구현도 단순합니다.

개략적 설계안#

  • 개략적 설계는 다음으로 나눌 수 있습니다.
    • 무상태 서비스
    • 상태유지(stateful) 서비스
    • 3자 서비스 연동

개력족 설계

무상태 서비스#

  • 무상태 서비스는 로그인, 회원가입, 사용자 프로파일 표시 등을 처리하는 전통적인 요청/응답 서비스입니다.

상태 유지 서비스#

  • 채팅 서비스는 상태 유지가 필요합니다.
  • 클라이언트가 채팅 서버와 독립적인 네트워크 설정을 유지해야 합니다.

제 3자 서비스 연동#

  • 제3자 서비스는 푸시 알림입니다. 새 메시지를 받았다면 설사 앱이 실행 중이지 않더라도 알림을 받아야 합니다.

규모 확장성#

  • 트래픽 규모가 낮으면 얼마 되지 않을 때는 방금 설명한 모든 기능을 서버 한 대로 구현할 수 있습니다.
  • 아래는 그 시작 포인트입니다.

규모 확장성

  • 채팅 서비는 클라이언트 사이에 메시지를 중계하는 역할을 담당합니다.
  • 접속상태 서버는 사용자의 접속 여부를 관리합니다.
  • API 서버는 로그인, 회원가입, 프로파일 변경 등 그 외 나머지 전부를 처리합니다.
  • 알림 서버는 푸시 알림을 보냅니다.
  • 키-값 저장소에는 채팅 이력을 보관합니다.

저장소#

  • 채팅 시스템이 다루는 데이터는 보통 두 가지입니다.
    • 첫 번째는 사용자 프로파일, 설정, 친구 목록처럼 일반적인 데이터입니다.
    • 두 번째는 유형의 데이터는 채팅 시스템에 고유한 데이터로 바로 채팅 이력입니다.
      • 페이스북이나 왓츠앱은 매일 600억 개의 메시지를 처리합니다.
  • 키-값 저장소는 아래의 추천점이 있습니다.
    • 수평적 규모확장이 쉽습니다.
    • 키-값 저장소는 데이터 접근 지연시간(latency)가 낮습니다.
    • 관계형 데이터베이스는 데이터 가운데 롱 테일에 해당하는 부분을 잘 처리하지 못합니다.
    • 많은 안정적인 채팅 시스템은 키-값 저장소를 채택할 수 있습니다.

데이터 모델#

  • 1:1 채팅을 위한 메시지 테이블과 그룹 채팅을 위한 메시지 테이블이 있습니다.

image

메시지 ID#

  • message_id의 값은 고유해야 합니다.
  • ID 값은 정렬 가능해야 하며 시간 순서와 일치해야합니다.

3단계 상세 설계#

서비스 탐색#

  • 서비스 탐색 기능의 주된 역할은 클라이언트에게 가장 적합한 채팅 서버를 추천하는 것입니다.
  • 대표적인 오픈 소스 솔루션으로 아파치 주키퍼가 있습니다.

서비스 탐색

메시지 흐름#

1:1 채팅 메시지 처리 흐름#

1:1 채팅 메시지 처리 흐름

여러 단말 사이의 메시지 동기화#

  • 단말기마다 cur_max_message_id 를 들고 있으며 최신화 정보를 유지합니다.

소규모 그룹 채팅에서의 메시지 흐름#

소규모 그룹 채팅

접속 상태 표시#

사용자 로그인#

  • 사용자가 로그인 하면, last_active_at 타임 스탬프 값을 키-값 저장소에 보관합니다.

로그아웃#

  • 키-값 저장소에 보관된 사용자 상태가 online-offline 으로 바꿉니다.

접속 장애#

  • 주기적 박동 검사를 통해 접속 장애 검사를 합니다.

상태 정보의 전송#

  • 그룹 크기가 적을 때는 발행-구독 모델을 사용하는 것이 좋은 방법일 수 있습니다.
  • 그러나 커지는 경우에는 수동으로 하도록 유도해야합니다.

4단계 마무리#

  • 아래의 내용에 대해 더 이야기해볼 수 있습니다.
    • 채팅 앱을 확장하여 사진이나 비디오 등의 미디어를 지원하도록 하는 방법
    • 종단 간 암호화: 왓츠앱은 메시지 전송에 있어 좋단 간 암호화를 지원합니다.
    • 캐시: 클라이언트에 이미 읽은 메시지를 캐시해 두면 서버와 주고받는 데이터 양을 줄일 수 있습니다.
    • 로딩 속도 개선: 슬랙은 사용자의 데이터, 채널 등을 지역적으로 분산하는 네트워크를 구축하여 앱 로딍 속도를 개선했습니다.
    • 오류 처리
      • 채팅 서버 오류: 서버가 죽을 경우, 서비스 탐색 기능이 동작하여 클라이언트에게 새로운 서버를 배정하고 다시 접속할 수 있도록 해야합니다.
      • 메시지 재전송: 재시도나 큐는 메시지의 안정적 전송을 보장하기 위해 흔히 사용됩니다.
Last updated on