채팅 시스템 개발

2024. 10. 14. 15:20·프로젝트 정리/인턴

1. 개발 언어

처음이라 Learning curve가 발생하지만 Nullsafe한 Kotlin으로 개발해보기로 선택

 

2. Framework

Spring Boot Framework

 

3. 채팅 서버 메시지 처리 방식

내가 개발하는 것은 1대1 채팅방 시스템

근데 유튜브 라이브의 경우 HTTP Polling 방식을 이용해 개발됐다는 내용을 찾았다.

https://www.reddit.com/r/csharp/comments/o0jffx/why_is_youtube_using_polling/?rdt=64177

 

From the csharp community on Reddit

Explore this post and more from the csharp community

www.reddit.com

HTTP Polling의 경우 기본 동작은 라이브 chat을 얻어오는 API를 일정 간격마다 호출해 새로운 메시지를 확인하는 식이다.

이는 서버와 클라이언트 간에 지속적인 연결(WebSocket)을 유지하지 않기 때문에, 클라이언트가 주기적으로 요청을 보내는 방식이다.

 

근데 사용자 입장에서 메시지가 10초 이후에 전달받으면 부정적 경험이므로 유튜브는 새로운 메시지가 있을 때는(폴링 주기를 1초 이내로 줄이는 방식) 적응형 폴링 방식을 이용한다고 한다. 새로운 메시지가 있는지 여부는 어떻게 아는지 궁금하였는데 서버 response를 받아올 때 서버에서 새로운 데이터가 있는지 없는지 여부를 아마 함께 보내주는 식으로 작동할 거 같다는 생각이다. 

 

유튜브의 경우 사용자가 매우 많아 이 방식을 택했다고 하는데 내가 하는 건 1대1 채팅방이며 사용자가 채팅방을 나가면 연결을 유지할 필요가 없기 때문에 WebSocket 방식 채택. 또한 메시지의 순서가 섞이거나 서로 다른 메시지를 본다는 가정 자체가 이상함. 

 

4. 채팅 메시지 저장소 : NoSQL인 MongoDB 선택

 

5. Message Broker

 

Redis Pub/sub 는 발행/구독 메시징 패러다임을 따르는 비동기 통신 모델이다. 이 방식은 발행자와 구독자가 서로 직접 연결되지 않고 채널을 통해 메시지를 교환한다. 이때 발행자는 특정 수신자를 몰라도 되고, 구독자는 필요한 메시지만 수신할 수 있습니다.

출처 : https://www.happykoo.net/@happykoo/posts/81

 

 

기본 사용법 : SUBSCRIBE 명령어로 원하는 채널에 구독한다. PUBLISH 명령으로 해당 채널에 메시지를 발행한다.

UNSUBSCRIBE를 사용해 구독을 해제한다.

 

메시지 전달 형식

Redis의 Pub/Sub에서는 발행된 메시지를 한 번만 전달한다. 만약 구독자가 메시지를 처리하지 못하거나 네트워크 문제가 발생하면 해당 메시지는 유실된다. 메시지는 다음과 같은 세 가지 유형으로 전송된다. subscribe : 채널에 성공적으로 구독할 때 전송된다. unsubscribe : 채널 구독 해제시 전송된다. message : 발행된 메시지를 수신할 때 전송된다.

 

 

Redis 패턴 매칭 구독 지원 : PSUBSCRIBE news.* 이를 통해 news.art , news.music 등과 같은 채널의 메시지를 수신할 수 있다. 

 

Redis의 Pub/Sub는 메시지를 발행하고 구독하는 시스템이지만, Redis의 키 공간과는 독립적입니다. 이 개념을 조금 더 쉽게 설명하면 다음과 같습니다.


1. Redis의 키 공간과 Pub/Sub의 차이점

  • Redis의 키 공간: 각 데이터베이스(DB)는 고유의 키-값 쌍을 저장합니다. 데이터베이스 번호(DB 번호)로 분리됩니다. 예를 들어, DB 0과 DB 1은 서로 다른 데이터 집합을 가질 수 있습니다.
  • Redis의 Pub/Sub: 채널에 메시지를 발행하면, 이 메시지는 Redis 서버 전체에 전파됩니다. 메시지를 구독하는 클라이언트는 특정 데이터베이스(DB 번호)와 관계없이 모든 메시지를 수신할 수 있습니다.

2. 예제: DB 간 메시지 전달

Redis Pub/Sub는 데이터베이스 번호에 영향을 받지 않기 때문에, 서로 다른 DB에서 발행된 메시지를 구독할 수 있습니다.

시나리오 예시:

  1. 10번 DB에서 PUBLISH 명령어로 메시지를 발행합니다.
  2. bash
    redis-cli -n 10 # 10번 DB 접속
    PUBLISH my_channel "Hello from DB 10!"
  3. 1번 DB에 있는 구독자가 my_channel 채널을 구독하고 있다면, 이 메시지를 받을 수 있습니다.1번 DB의 구독자 출력:
  4. bash
    redis-cli -n 1 # 1번 DB 접속
    SUBSCRIBE my_channel
  5. 1번 DB의 구독자 출력:
  6. 1) "message"
    2) "my_channel"
    3) "Hello from DB 10!"

 

Redis 7.0에서는 Shared Pub/Sub가 도입되어 기존 글로벌 pub/sub의 성능 문제를 해결하기 할 수 있게 되었다.

 

기존 글로벌 pub/sub와 차이점은 메시지가 전체 클러스터에 전달되지 않고 , 특정 Shard 내에서만 전달된다. 

 

메시지 전송을 제한된 노드 집합으로 축소하기 때문에 클러스터 간 네트워크 트래픽과 부하를 크게 줄인다.

 

수평적 확장 가능 : 더 많은 Shard를 추가하여 Pub/Sub 용량을 확장할 수 있다. 

 

5. Sharded Pub/Sub vs 글로벌 Pub/Sub 비교

 

항목Sharded Pub/Sub글로벌 Pub/Sub

항목 Sharded Pub/Sub 글로벌 Pub/Sub
메시지 전달 범위 특정 Shard 내 노드 모든 클러스터 노드
성능 노드 간 네트워크 부하가 적음 모든 노드에 메시지를 전달하므로 부하가 큼
확장성 Shard 추가를 통해 수평적 확장 가능 확장에 따른 성능 저하 발생 가능
명령어 SSUBSCRIBE, SPUBLISH, SUNSUBSCRIBE 사용 SUBSCRIBE, PUBLISH, UNSUBSCRIBE 사용

 

 

참조 :

https://inpa.tistory.com/entry/REDIS-%F0%9F%93%9A-PUBSUB-%EA%B8%B0%EB%8A%A5-%EC%86%8C%EA%B0%9C-%EC%B1%84%ED%8C%85-%EA%B5%AC%EB%8F%85-%EC%95%8C%EB%A6%BC

 

🗃️ REDIS의 PUB/SUB 기능 (채팅 / 구독 알림)

Redis Publish / Subscribe Publish / Subscribe 란 특정한 주제(topic)에 대하여 해당 topic을 구독한 모두에게 메시지를 발행하는 통신 방법으로 채널을 구독한 수신자(클라이언트) 모두에게 메세지를 전송 하

inpa.tistory.com

 

메시지 브로커랑 카프카 사용 시나리오

Kafka 기본 개념

- Kafka Topic:

  • Topic은 Kafka 내에서 메시지들을 구분해서 저장하는 논리적 단위이다.
  • Kafka는 모든 메시지를 주제별(Topic)로 관리한다. Producer가 특정 Topic에 메시지를 보내면 그 메시지는 해당 Topic에 순서대로 저장되고, Consumer는 이 Topic을 구독하여 메시지를 가져간다.
  • 예시
    • topic 이름이 chat-topic이라 했을 때 Producer가 "Hello"라는 메시지를 chat-topic에 게시하면 , 이 메시지는 chat-topic에 기록된다. Consumer는 chat-topic을 구독하고 이 메시지를 읽어갈 수 있다.

Kafka Topic의 구조와 동작 원리

Partition (파티션)

  • Kafka의 각 Topic은 하나 이상의 Partition으로 구성된다.
  •  

 

 

채팅 룸당 카프카 컨수머가 생성된다 -> topic이 여러개 생성된다 -> 이를 담당하는 컨수머가 여러개다

 

하나의 topic으로 처리 -> 하나의 컨수머만 있다. -> 이를 각 채팅서버가 consuming 한다? -> 그러면 redis pub sub 구조랑 다른게 뭐지? 왜 카프카를 쓰는거지? 

 

이어서 작성...

 

1대1 채팅방 뿐만 아니라 다수 채팅방도...
채팅방 내에서 사진에 각 코멘트 남기기 기능?
대화 내용 저장 및 변환 가능?

'프로젝트 정리 > 인턴' 카테고리의 다른 글

스프링 시큐리티 내부구조 총정리(3)  (0) 2024.11.05
Spring Security (스프링 시큐리티 내부 구조 총정리 -2)  (0) 2024.10.21
Spring Security (스프링 시큐리티 내부 구조 총정리 -1)  (0) 2024.10.18
뻘짓하며 배우는 CORS  (0) 2024.10.16
'프로젝트 정리/인턴' 카테고리의 다른 글
  • 스프링 시큐리티 내부구조 총정리(3)
  • Spring Security (스프링 시큐리티 내부 구조 총정리 -2)
  • Spring Security (스프링 시큐리티 내부 구조 총정리 -1)
  • 뻘짓하며 배우는 CORS
Ark B
Ark B
  • Ark B
    기록
    Ark B
  • 전체
    오늘
    어제
    • 분류 전체보기 (35)
      • 개인 프로젝트 정리 (1)
        • 채팅 프로젝트 (0)
      • JAVA (9)
      • CS (7)
      • 프로젝트 정리 (6)
        • 인턴 (5)
        • 졸업프로젝트 (0)
      • 코딩테스트 (1)
      • 클린 코드 (3)
      • 책 정리 (1)
        • Effective Java (0)
        • 모던 자바인 액션 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    오블완
    티스토리챌린지
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Ark B
채팅 시스템 개발
상단으로

티스토리툴바