메신저앱 작동원리

임정환·2023년 9월 11일
0

그냥 우연히 든 생각... 1대1 채팅같은 경우 (e.g. 텔넷) 서로의 연결이 성립되어 있으니까 언제든지 양방향 통신이 가능하다. 근데 , 그럼 '카카오톡' , '페이스북 메신저'와 같은 app들은 어떻게 A->B로 메시지를 보내면 바로 B에게 푸쉬를 해주지?

WebSocket

기존의 HTTP 프로토콜의 문제점은 클라이언트 "A"가 "B"에게 요청을 보내고 , 응답을 받으면 모든 연결이 종료된다. 또한, 이전의 상태를 기억하지 않기때문에 ( 세션같은 기법으로 상태를 유지할 수는 있지만 ) 매번 새롭게 연결을 설정해줘야한다.

메신저 앱 디자인

메신저앱은 텔넷과 같이 1대1로 연결이 설정되어 메세지를 주고받는게 아니라 "유저1" <-> "서버" <-> "유저2" 의 방식으로 통신하게 된다. 그러면 , "유저1"이 "유저2"에게 보낸 메세지를 "서버"가 수신하면 "서버"가 "유저2"에게 해당 메세지를 알려줘야한다.( 카톡이 도착하면 , 핸드폰에 알람이 오듯이)
몇 가지 방법이 존재하겠는데 , 한번 알아보장

  • Polling
    주기적으로 "저한테 메세지가 도착했나요?"라고 서버에게 질의하는 방법이다.
    시간 간격은 정하기 나름이겠지만 , 메세지가 도착하지 않았을 경우 무의미한 리퀘스트가 많아질 뿐더러 서버의 트래픽을 굉장히 많이 잡아먹을 것이다.
  • Long Polling
    Polling과 비슷한 기법이다. 클라이언트가 "저한테 메세지가 도착했나요?" 라고 서버에 질의하면 , 서버는 연결을 유지한채로 해당 클라이언트에게 메시지가 도착할때까지 기다리다가 메세지가 도착하면 그때서야 response를 해준다.
    물론 계속해서 해당 request를 서버측에서 잡고 있을 수는 없으므로 , 특정 시간간격이 지나면 Polling처럼 연결을 놓아주도록 한다.
  • WebSocket
    HTTP 요청이후 연결을 유지하고 있는다. 마치 TCP연결 설정처럼! 연결이 수립된 상태에서 , 클라이언트와 서버는 자유롭게 양방향 통신을 할 수 있게된다.
    실시간 채팅 , 게임 등의 서비스에서 많이 사용되는 방식이다.

시스템 디자인

그럼 웹소켓을 사용할 때 , 어떻게 채팅앱이 디자인될까?

  • 일반적인 채팅은 오픈 커넥션을 유지하는 chat 서버에서 담당한다.
  • 일반적인 API요청은 REST를 사용하는 API 서버에서 담당한다.

채팅 서비스

메시지큐를 사용한 ( MQTT 등등 ) 방법이 있을 수 있겠다. 메시지 큐는 Publisher(이하 발행자)와 Subscriber(이하 구독자)로 역활을 구분하고 , 발행자가 특정 서비스 큐에 어떠한 작업을 '발행'하면 해당 큐를 구독하던 '구독자'는 event-driven 방식으로 task를 진행한다. 더 자세한건 , 나중에 다루겠다.
다시 돌아와서 , 로그인한 유저 A와 B가 있고 로그아웃한 유저 C가 있다고 가정해보자.
A가 B에게 메시지를 보낸다면 , 아래와 같은 과정이 발생할 것이다.

  • A가 websocket연결이 수립된 chat server1에게 메시지를 보낸다.
  • chatserve1이 user B의 메시지큐에 메시지를 넣어준다.
  • 해당 큐를 구독하던 서비스들에게 알림이 간다.
    • message DB
    • chatserver3
  • 해당 큐를 구독중인 chatserver3에게 알람이 간다.
  • chatserve3는 유저B에게 다시 알려준다.
  • message DB 또한 메시지 큐를 바라보고 , 큐에 들어온 메시지들을 DB에 저장한다.
    • 엄청난 양의 트래픽을 감당하기 위함과 서비스의 특성을 고려해서( e.g. join이 일어나지 않고 단순한 조회만이 이루어짐 ) ACID를 지원하는 관계형 DB보다 noSQL DB가 더 좋은 선택이 될 것이다.
profile
CS 박제

0개의 댓글

관련 채용 정보