Top 6 메신저 Db 구조 26869 Good Rating This Answer

You are looking for information, articles, knowledge about the topic nail salons open on sunday near me 메신저 db 구조 on Google, you do not find the information you need! Here are the best content compiled and compiled by the https://chewathai27.com/to team, along with other related topics such as: 메신저 db 구조 카카오톡 db 구조, 채팅 DB, 채팅 DB 저장, 웹 메신저 만들기, 카카오 데이터베이스, 메신저 ERD, 친구 목록 ERD, 메신저 동작 원리


관계형 DB에서, 스키마를 설계하는 법! 5분 순삭 | 디모의 5분 코딩상식
관계형 DB에서, 스키마를 설계하는 법! 5분 순삭 | 디모의 5분 코딩상식


[초보자들 EP.07] 미션 : 메신저 만들기(Summer편) – Bsidesoft co.

  • Article author: www.bsidesoft.com
  • Reviews from users: 21891 ⭐ Ratings
  • Top rated: 3.0 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about [초보자들 EP.07] 미션 : 메신저 만들기(Summer편) – Bsidesoft co. 메신저를 만들자! 무엇을 기억할까? 데이터 골라내기; 어떻게 기억할까? DB 설계하기; 어떻게 주고 받을까? API 문서 작성하기 … …
  • Most searched keywords: Whether you are looking for [초보자들 EP.07] 미션 : 메신저 만들기(Summer편) – Bsidesoft co. 메신저를 만들자! 무엇을 기억할까? 데이터 골라내기; 어떻게 기억할까? DB 설계하기; 어떻게 주고 받을까? API 문서 작성하기 …
  • Table of Contents:

메신저를 만들자!

무엇을 기억할까 데이터 골라내기

어떻게 기억할까 DB 설계하기

어떻게 주고 받을까 API 문서 작성하기

어떻게 효과적으로 주고 받을 수 있을까 롱폴링!

어찌되었든 완성…

[WebGL] WebGL #4 – WebGL 작동 방법의 이해 1

[책] 거침없이 배우는 SWIFT

[WebGL] WebGL #2 – 기초 2

[js] CSV 사용하기

[초보자들 EP.07] 미션 : 메신저 만들기(Summer편) - Bsidesoft co.
[초보자들 EP.07] 미션 : 메신저 만들기(Summer편) – Bsidesoft co.

Read More

대규모 시스템 설계 기초 – 12장 채팅 시스템 설계

  • Article author: dong-life.tistory.com
  • Reviews from users: 10089 ⭐ Ratings
  • Top rated: 3.8 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about 대규모 시스템 설계 기초 – 12장 채팅 시스템 설계 이번에는 페이스북 메신저와 유사한 채팅 앱을 설계해본다. … DB를 어떤 것을 쓸거냐 하는 질문에서 중요하게 따져야 할 부분은 데이터의 유형과 … …
  • Most searched keywords: Whether you are looking for 대규모 시스템 설계 기초 – 12장 채팅 시스템 설계 이번에는 페이스북 메신저와 유사한 채팅 앱을 설계해본다. … DB를 어떤 것을 쓸거냐 하는 질문에서 중요하게 따져야 할 부분은 데이터의 유형과 … 채팅 앱이라고 했을 때 사람들이 떠올리는 것은 제각각이다. 그러니 요구사항을 확실하게 해 두는 것이 중요하다. 예를 들어 면접관이 생각하고 있는게 일대일 채팅 앱일 때 그룹 채팅 앱을 설계하면 곤란하다. 1..
  • Table of Contents:

JD의 블로그

대규모 시스템 설계 기초 – 12장 채팅 시스템 설계 본문

대규모 시스템 설계 기초 - 12장 채팅 시스템 설계
대규모 시스템 설계 기초 – 12장 채팅 시스템 설계

Read More

메신저 개발을 위한 NoSQL 데이터 구조

  • Article author: stalk.tistory.com
  • Reviews from users: 14880 ⭐ Ratings
  • Top rated: 3.5 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about 메신저 개발을 위한 NoSQL 데이터 구조 메신저 개발을 위한 NoSQL 데이터 구조. yohany 2016. 9. 6. 12:18. Parse-server 를 기반으로한 메신저를 개발하기 위하여 가장 먼저 데이터 모델링 부터 진행하였다. …
  • Most searched keywords: Whether you are looking for 메신저 개발을 위한 NoSQL 데이터 구조 메신저 개발을 위한 NoSQL 데이터 구조. yohany 2016. 9. 6. 12:18. Parse-server 를 기반으로한 메신저를 개발하기 위하여 가장 먼저 데이터 모델링 부터 진행하였다. Parse-server 를 기반으로한 메신저를 개발하기 위하여 가장 먼저 데이터 모델링 부터 진행하였다. Parse-server 는 기본적으로 MongoDB에 데이터를 저장관리하도록 하고 있다. 즉 아래 데이터 모델링은 RDB 가 아..
  • Table of Contents:
메신저 개발을 위한 NoSQL 데이터 구조
메신저 개발을 위한 NoSQL 데이터 구조

Read More

채팅 시스템 설계

  • Article author: velog.io
  • Reviews from users: 45528 ⭐ Ratings
  • Top rated: 4.9 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about 채팅 시스템 설계 페이스북 메신저는 HBase를 사용하고 디스코드는 카산드라 NoSQL을 사용하고 있다. 데이터 모델. 1:1 채팅을 위한 메시지 테이블. 이 테이블의 기본 키( … …
  • Most searched keywords: Whether you are looking for 채팅 시스템 설계 페이스북 메신저는 HBase를 사용하고 디스코드는 카산드라 NoSQL을 사용하고 있다. 데이터 모델. 1:1 채팅을 위한 메시지 테이블. 이 테이블의 기본 키( … 가상 면접 사례로 배우는 대규모 시스템 설계 기초 챕터 12 스터디
  • Table of Contents:

독서

과제

설계안

폴링

롱 폴링

웹소켓

무상태 서비스

상태 유지 서비스

제 3자 서비스 연동

규모 확장성

저장소

서비스 탐색

메시지 흐름

마무리

채팅 시스템 설계
채팅 시스템 설계

Read More

(ERD설계 및 MySQL연습) 카카오톡 채팅목록 화면 ERD 설계, DataGrip을 사용하여 메시창을 보여주는 MySQL 한방 쿼리 작성하기

  • Article author: yusang.tistory.com
  • Reviews from users: 43258 ⭐ Ratings
  • Top rated: 3.3 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about (ERD설계 및 MySQL연습) 카카오톡 채팅목록 화면 ERD 설계, DataGrip을 사용하여 메시창을 보여주는 MySQL 한방 쿼리 작성하기 이제 우리가 가지고 있는 데이터를 아래와 같이 제공할 수 있도록 한방 쿼리를 작성해 봅시다. Room 테이블에 imageUrl칼럼이 필요하기 때문에 아래와 … …
  • Most searched keywords: Whether you are looking for (ERD설계 및 MySQL연습) 카카오톡 채팅목록 화면 ERD 설계, DataGrip을 사용하여 메시창을 보여주는 MySQL 한방 쿼리 작성하기 이제 우리가 가지고 있는 데이터를 아래와 같이 제공할 수 있도록 한방 쿼리를 작성해 봅시다. Room 테이블에 imageUrl칼럼이 필요하기 때문에 아래와 … 오늘의 목표!! 카카오톡 채팅 목록 화면을 ERD설계를 해보고, 이를 보여주는 MySQL 쿼리문을 작성해 봅시다! DataGrip을 실행 후 kakaoDB라는 데이터 베이스를 생성해 줍시다 schemas에 생성된 kakaoDB선택 후 J..
  • Table of Contents:

YS’s develop story

(ERD설계 및 MySQL연습) 카카오톡 채팅목록 화면 ERD 설계 DataGrip을 사용하여 메시창을 보여주는 MySQL 한방 쿼리 작성하기 본문

티스토리툴바

(ERD설계 및 MySQL연습) 카카오톡 채팅목록 화면 ERD 설계,  DataGrip을 사용하여 메시창을 보여주는 MySQL 한방 쿼리 작성하기
(ERD설계 및 MySQL연습) 카카오톡 채팅목록 화면 ERD 설계, DataGrip을 사용하여 메시창을 보여주는 MySQL 한방 쿼리 작성하기

Read More

(ERD설계 및 MySQL연습) 카카오톡 채팅목록 화면 ERD 설계, DataGrip을 사용하여 메시창을 보여주는 MySQL 한방 쿼리 작성하기

  • Article author: www.stechstar.com
  • Reviews from users: 8988 ⭐ Ratings
  • Top rated: 3.2 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about (ERD설계 및 MySQL연습) 카카오톡 채팅목록 화면 ERD 설계, DataGrip을 사용하여 메시창을 보여주는 MySQL 한방 쿼리 작성하기 네이버 라인은 왜 카카오톡보다 병목현상이 적을까? [IT전문 미디어 블로그=딜라이트닷넷] 지난 달 28일 모바일메신저 카카오톡이 4시간동안 먹통이 … …
  • Most searched keywords: Whether you are looking for (ERD설계 및 MySQL연습) 카카오톡 채팅목록 화면 ERD 설계, DataGrip을 사용하여 메시창을 보여주는 MySQL 한방 쿼리 작성하기 네이버 라인은 왜 카카오톡보다 병목현상이 적을까? [IT전문 미디어 블로그=딜라이트닷넷] 지난 달 28일 모바일메신저 카카오톡이 4시간동안 먹통이 … 오늘의 목표!! 카카오톡 채팅 목록 화면을 ERD설계를 해보고, 이를 보여주는 MySQL 쿼리문을 작성해 봅시다! DataGrip을 실행 후 kakaoDB라는 데이터 베이스를 생성해 줍시다 schemas에 생성된 kakaoDB선택 후 J..
  • Table of Contents:

YS’s develop story

(ERD설계 및 MySQL연습) 카카오톡 채팅목록 화면 ERD 설계 DataGrip을 사용하여 메시창을 보여주는 MySQL 한방 쿼리 작성하기 본문

티스토리툴바

(ERD설계 및 MySQL연습) 카카오톡 채팅목록 화면 ERD 설계,  DataGrip을 사용하여 메시창을 보여주는 MySQL 한방 쿼리 작성하기
(ERD설계 및 MySQL연습) 카카오톡 채팅목록 화면 ERD 설계, DataGrip을 사용하여 메시창을 보여주는 MySQL 한방 쿼리 작성하기

Read More

[메신저 프로그램 ] #5. Client /DB/Packet

  • Article author: sanghun219.tistory.com
  • Reviews from users: 26234 ⭐ Ratings
  • Top rated: 3.9 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about [메신저 프로그램 ] #5. Client /DB/Packet 테스트만 해보면 그만이겠네요. 단일 클라이언트 테스트가 끝난뒤 테스트 클라이언트 코드들을 모두 지우고 GUI와 연동되도록. 설계를 했습니다. 이벤트가 … …
  • Most searched keywords: Whether you are looking for [메신저 프로그램 ] #5. Client /DB/Packet 테스트만 해보면 그만이겠네요. 단일 클라이언트 테스트가 끝난뒤 테스트 클라이언트 코드들을 모두 지우고 GUI와 연동되도록. 설계를 했습니다. 이벤트가 … 개발한지 한 달이 넘어갔습니다. 현재까지는 문제가 없는데 퀄리티가 마음에 안드는건 어쩔수가 없네요.. 서버-클라이언트 간에 일어나는 통신은 이제 전혀 문제가 없습니다. 스트림으로 데이터 직렬화 한 후 전달..
  • Table of Contents:
[메신저 프로그램 ] #5 Client DBPacket

티스토리툴바

[메신저 프로그램 ] #5. Client /DB/Packet
[메신저 프로그램 ] #5. Client /DB/Packet

Read More


See more articles in the same category here: https://chewathai27.com/to/blog.

[초보자들 EP.07] 미션 : 메신저 만들기(Summer편)

안녕하세요! 오랜만에 돌아온 초보자들2 Summer입니다.

시간이 쏜살같이 지나 2017년 새해가 밝았습니다. (모두 새해복 많이 받으세요!)

올해는 과연 개발왕이 될 수 있을런지… @_@

앞서 Dimanche가 지난번 프로젝트였던 메신저 만들기 글을 올렸습니다.

>> 재미와 감동이 넘치는 Dimanche의 메신저 만들기 글읽기

그럼 이번 Summer의 메신저 정복기를 함께 보실까요?

메신저를 만들자!

이번 프로젝트는 바로 메신저였습니다. 메신저 하면 바로 떠오르는 노란색의 메신저부터 시작해서 초록색, 파란색 등 여러가지 서비스가 생각나는데요ㅡ 저희는 아주 간단한 수준의 메신저를 만들기로 했습니다.

요구사항은 Dimanche의 글에서 언급된 바와 같은데요, 간단하게 정리하자면

주고 받는 것은 텍스트의 글이고,

대화 상대는 1명-무조건 1:1의 대화만 가능하고,

주소록 추가와 별명 수정은 가능하나 친구 삭제는 없는,

그런 아주 간단한 수준의 메신저였습니다.

위에서 말한 노란색 메신저를 사용자로 쓸 때는 참 쉬워보이고(?) 때로는 별로라고 불만을 토로하기도 했는데 막상 제가 메신저를 만들려고 하니 제 요구사항을 수용하기도 버겁다는 생각이 들면서… 평소 쓰던 메신저들의 개발자들에게 죄송한 마음과 존경심을 갖게 되었다는(먼산) (역시 사람은 자기가 해봐야 합니다)

어쨌든, 기본적으로 메신저라 함은 메세지를 주고 받을 수 있는 프로그램을 말합니다.

결국 (어떤 메시지를) (어떻게 주고받을것인가)가 핵심임을 알 수 있습니다.

저 둘을 해결하면 메신저는 끝나는 것!!! 하나하나 정복해 봅시다.

차암~ 쉽죠^^?(과연…)

무엇을 기억할까? 데이터 골라내기

프로그램에서 제일 중요한 것은 ‘데이터’입니다. 데이터라 함은 중요한 것, 기억해야 할 것을 의미하는데 메신저 같은 경우에는 주고받는 메시지가 대표적인 데이터가 되겠죠.

무엇을 기억할지는 기획을 하면서 판단해볼 수 있습니다.

예를 들어 주소록을 보자면… 주소록의 요구사항은 다음과 같았습니다.

채팅 페이지에는 연락처 목록과 채팅화면이 있다.

사용자는 연락처를 추가, 삭제, 별명 변경을 할 수 있다.

연락처에 새 메시지(읽지 않은) 개수가 표시된다.

이를 충족하기 위해 다음과 같이 화면구성을 했고

다음과 같이 용어집을 작성했습니다.

화면에 보면 많은 숫자와 글자들이 있는데요, 저기서 있는 모든 수치들이 기억될 필요는 없습니다.

예를 들면 친구목록 옆에 10명의 숫자는 따로 기억하지 않아도 됩니다. 왜냐하면 주소록으로 등록된 목록의 숫자를 세면 알 수 있으니까요. 또 화면에는 보이지 않지만, 필요에 따라 주소록을 언제 등록했는지 기억해야 할 수도 있습니다.

이렇게 기획한 문서를 바탕으로 무엇을 기억해야할 지 뽑아낸 것을 “데이터 엔티티”라고 합니다.

어떻게 기억할까? DB 설계하기

데이터 엔티티를 뽑아냈다면, 이제 실제로 그 데이터를 어떻게 기억해야할 지 정해야 합니다. 데이터를 기억하는 방법은 여러가지가 있습니다. 변수에 임시로 저장해둘수도 있고, DB처럼 미리 정해진 형식에 데이터를 저장하고 관리할 수 있습니다. DB도 여러가지 종류가 있어서 데이터의 성격과 개발환경에 따라 가장 적절한 것을 선택할 수 있는데, 저희는 클라이언트단에서 Session storage와 Indexed DB를, 서버에서 mySQL을 사용했습니다.

처음엔 DB에 그냥 제가 정한 데이터 엔티티를 데이터 타입에만 맞게 잘 넣으면 안되나!?!? 라고 생각했습니다.

그래서 다음과 같이 DB를 설계했습니다.

주소록엔 본인 전화번호, 상대방 전화번호, 상대방 별명을,

메시지엔 보낸 사람, 받는사람, 내용, 작성날짜를 필요한대로 넣었습니다.

참 솔직하고 정직한 DB죠..^^;;

물론 저렇게 해도 프로그램은 잘 돌아갑니다. (좀 비효율적일지라도)

하지만 메시지 DB만 봤을 때, 주소록에 등록되지 않은 사람들이 메시지를 받고 보낼 수 있게 되어있습니다. 물론 누군가 날 먼저 주소록에 등록해서 메시지를 보낼 수 있지만, 그렇다하더라도 그 누군가는 주소록에 등록한 번호에 대해서만 메시지를 보낼 수 있어야 합니다. 즉, 정확하지 않은 데이터가 저장될 수 있다는 것 입니다.

이를 방지하게 위해 관계형 DB를 이용할 수 있습니다. 관계형 DB는 데이터를 테이블 형식으로 데이터를 저장하는 DB를 말하는데요, 테이블간의 관계 및 제약 등을 통해 좀 더 확실하고 정확한 데이터를 저장하고 그를 효율적으로 활용할 수 있도록 합니다.

주소록과 메시지 테이블간의 관계를 이용해 다음과 같이 DB구조를 바꿨습니다. 메시지에서 발신자-수신자로 저장하는 것이 아니라, 주소록id 번호를 저장하게 했습니다. 이를통해 주소록에 등록된 사람들이 메시지를 보낼 수 있도록 보장했고, 더불어 발신자-수신자 번호를 중복 저장하는 것도 막아내는 효과를 누릴 수 있었습니다.

프로그램에서 데이터가 정말 중요한 만큼 어떻게 하면 중복없이! 확실하게 보장된! 데이터만 저장할 수 있을 지도 열심히 공부해야겠다고 생각했습니다.

어떻게 주고 받을까? API 문서 작성하기

자 이제 어떤 데이터가 필요한지도 알았고 DB구조도 어떻게 되는지 정해졌습니다. 그렇다면 이제 데이터를 보내기만 하면 되는데… 어떻게 보내야할까요?

답은 인터넷.. HTTP 통신이겠으나…(헉)

구체적으로 어떻게 서버와 클라이언트가 상호간에 어떤 데이터를 어떤 형식으로 주고 받을 것인지 정할 필요가 있습니다.

이를 위해 통신 API를 위한 JSON을 작성합니다. 이번 프로젝트에서는 클라이언트-서버 통신이 일어나는 부분에만 API JSON을 작성하면 되었습니다. 그것 부분은 로그인, 비밀번호 발급(회원가입), 비밀 번호 재발급, 메시지 받기, 메시지 전송하기 5부분이었습니다.

한 예로 회원 가입 부분은 다음과 같이 작성했습니다.

{ “etc”:{ “realurl”:”api/?member/getPw”, “request”:{ “phone”:”핸드폰 번호. 정규식은 /^01([0|1|6|7|8|9]?)([0-9]{3,4})([0-9]{4})$/g” }, “memo”:[ “비밀번호 얻기(회원가입)”, “회원 가입 실패 시 응답 메시지에 [error] 데이터가 전송됨”, “code:isMember:이미 가입을 한 사람인 경우 에러값” ], “error”:{ “code”:”isMember” } }, “auth”: { “status”:”logout” }, “data”:{ “result”:”success” } }

etc 부분은 데이터 구조와 데이터 내용을 설명하는 부분으로, 따로 API 문서를 작성해서 관리하는 것보다 여기서 하나로 관리하는 것이 효율적이라 여기에 적어 관리합니다.

realurl은 실제 요청을 보내는 url이며, request는 서버에 요청하는 값으로 밸리데이션이 필요한 경우 위에처럼 조건을 덧붙입니다.

실제 response로 받게 되는 부분은 ETC를 제외한 부분인데요, response의 구조는 얼마든지 달라질 수 있습니다.

저같은 경우 auth라는 키로 로그인 상태를 파악하고, data로 실제 요청에 대한 응답값을 받게 되어있습니다.

이렇게 JSON으로 작성을 해두면 다음과 같은 장점이 있습니다.

데이터형식이 통일되어 있으니 서버가 ASP든, PHP든 NODE든, 혹은 제가 만든 클라이언트의 메신저가 아니어도 데이터를 주고받을 수 있음 서버가 구축되지 않아도 JSON에 써놓은 데이터를 가지고 와서 그걸 바탕으로 클라이언트를?프로그래밍을 진행할 수 있음 따로 API 설명을 위한 문서작성을 할필요 없음(=덜귀찮음)

이런 이유로 이를 실무에서 적극적으로 활용하고 있습니다.

어떻게 효과적으로 주고 받을 수 있을까? 롱폴링!

지금은 노란 메신저로 이모티콘에 파일도 보내고 속도도 엄청 빠른게 당연하지만, 초기에는 통신 속도가 느려서 답답한 적이 있었다는 걸 기억하시나요..? (그때 번개도 나오고 막그랬는데말이죠..)

메신저의 생명은 빠른 의사소통! 어떻게 하면 효과적으로 빠르게 통신을 할 수 있을지 고민해볼 필요가 있습니다.

저희 메신저는 HTTP 환경으로 통신을 합니다. HTTP 통신은 기본적으로 클라이언트-서버간의 통신 프로토콜로 클라이언트에서 요청을 보내면 서버에서 응답을 하는 구조로 구성되어 있습니다. 간단한 구조에 쓰기 편하다는 장점이 있지만, 반대로 단점도 있습니다. HTTP에서는 서버의 정보가 갱신되었는지 아닌지를 알기 위해서는 클라이언트가 항상 먼저 요청을 보내야합니다. 만약에 서버에 갱신된 정보가 없으면 클라이언트가 보낸 요청은 헛수고가 된거죠. 제 메신저도 서버로 누가 자기에게 메시지를 보냈는지 알 방법이 없기때문에 서버에 주기적으로 물어보게 되어있습니다. 누군가 자기에게 메시지를 보내지 않았다면 헛수고가 된것이고, 이런 사용자가 많게되면 헛수고만 가득한 통신 부하만 생기게 되는 거죠.

한국인에게 특히나 더 괴로운 이 화면…..

이런 HTTP 통신의 단점을 보완하기 위해 클라이언트의 요청 없이도 서버에서 통신을 먼저 보낼 수 있는 푸시 서버, 저희가 이용한 “롱폴링” 등을 도입할 수 있습니다.

롱폴링은 HTTP 요청이 왔을 때 서버가 일정 시간 동안 응답을 대기 시키는 것을 말합니다. 만약 대기하는 동안 서버 측 데이터에 변화가 생기면 바로 응답을 반환하구요. 실제 보내줘야할 데이터가 있을 때만 응답을 하게 되니 쓸데없는 응답이 줄어들겠죠.

이를 구현하기 위해 setInterval함수와 for문 이용했습니다.

var intervalId, cnt; intervalId = setInterval(function(){ cnt++; //반복할 횟수를 카운트. if(cnt < 5){ //데이터가 있는 경우 바로 인터벌 해제하고 데이터 전송 if(storage[reqBody.phone] !== undefined || storage[reqBody.phone] !== []){ resBody = { auth:{status:'login'}, data: getMsg(reqBody.phone) }; clearInterval(intervalId); res.send(resBody); } } else { //최대 5회(5초)까지 롱폴링 시킴. clearInterval(intervalId); resBody = { auth:{status:'login'}, data: {} } res.send(resBody); } }, 1000); 롱폴링도 응답을 지연시키면서 서버의 리소스를 쓰게 되므로 절대적으로 좋은 것은 아닙니다. 상황에 맞게 가장 적절한 것을 선택하는 센스! 어찌되었든 완성… 글에는 적지 못했지만 구현하면서 어려웠던 점들이 참 많았습니다. Javscript의 스코프를 제대로 몰라서 undefined의 늪에 허우적 거리던 때, 비동기 통신을 제대로 몰라서 다시한 번 빠졌던 undefined의 늪.. 그리고 콜백 함수 지옥 등.. @_@… 그래도 다행이 동료 Dimanche와 상사분들의 도움으로 어찌 저찌 1.0버전을 완성했습니다. 로그인 메신저 메인 메신저 채팅화면 그래도 프로그램에 있어 가장 중요한 데이터를 찾고 저장하는 법, 그리고 그것을 교환하는 방식에 대해 전반적으로 경험해보고 배울 수 있었던 프로젝트였습니다. 마지막으로… 이번 프로젝트를 진행하면서 한가지 더 아쉬웠던 점은 이 프로젝트가 프로그래밍 실력을 쌓는 교육과정일 뿐만이 아니라 ‘실무를 배워나가는 과정’이기도 하다는것을 잊은 것이었습니다. 이제 어느정도 회사가 일하는 방식을 보고 배웠으니 제 프로젝트에서도 똑같이 적용해보며 실무에서 더 잘 쓸 수 있도록 했어야 했지만, 예전 습관처럼 개인 프로젝트하듯 프로그램을 만들고 있었습니다. (그래서 더 삽질을 하면서 시간이 오래걸렸구요..) 교육용 프로젝트 또한 실무를 배우기 위한 디딤돌임을 잊지 말자고 다짐을 했습니다. 올해도 힘을 내어 봅니다. 개발왕이 될 그날까지 화이팅! summer| bsidesoft 신입사원 디자인을 공부했던 섬머는 개발까지 해버리겠다는 욕심으로 개발자의 세계에 입문하게 되었습니다. 개발왕이 되어 멋진 제품을 만들어내는 꿈을 꾸고 있습니다. 코드, 디자인을 포함한 세상의 모든 아름다운 것들과 미드, 그리고 달리기를 좋아합니다. 이 글 공유하기: 트위터 Facebook

대규모 시스템 설계 기초

채팅 앱이라고 했을 때 사람들이 떠올리는 것은 제각각이다. 그러니 요구사항을 확실하게 해 두는 것이 중요하다.

예를 들어 면접관이 생각하고 있는게 일대일 채팅 앱일 때 그룹 채팅 앱을 설계하면 곤란하다.

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

어떤 채팅 앱을 설계하려는지 확실히 해 두는 것이 중요하다.

현재 시장에 나와있는 앱을 보면 페이스북 메신저, 위챗, 왓츠앱처럼 1:1 채팅에 집중하는 앱들이 있는가 하면 슬랙 같은 그룹 채팅에 중점을 둔 업무용 앱이나, 게임 채팅에 쓰이는 디스코드 같이 대규모 그룹의 소통과 응답지연이 낮은 음성 채팅에 집중하는 앱도 있다.

1. 1:1 채팅 앱인지 그룹 채팅 앱인지 물어보기

EX) 둘 다 지원할 수 있어야 한다.

2. 모바일 앱인지 웹 앱인지 물어보기

EX) 둘 다

3. 처리해야 하는 트래픽 규모는 어느 정도인지 물어보기

EX) DAU 기준으로 5천만명을 처리할 수 있어야 한다.

4. 그룹 채팅의 경우 인원 제한이 있는지 물어보기

EX) 최대 100명까지 참가할 수 있다.

5. 중요 기능으로 추가로 어떤 것이 있는지 물어보기 (첨부 파일 지원 등)

EX) 1:1 채팅, 그룹 채팅, 사용자 접속 상태 표시를 지원해야 한다. 텍스트 메시지만 주고 받을 수 있다.

6. 메시지 길이에 제한이 있는지 물어보기

EX) 100,000자 이하여야 한다.

7. 종단 간 암호화를 지원해야하는지 물어보기

EX) 현재로썬 필요없지만 시간이 남는다면 논의해볼 수 있다.

8. 채팅 이력은 얼마나 오래 보관해야 하는지 물어보기

EX) 영원히

이번에는 페이스북 메신저와 유사한 채팅 앱을 설계해본다.

이 앱은 다음과 같은 기능을 갖는다.

응답지연이 낮은 일대일 채팅 기능

최대 100명까지 참여할 수 있는 그룹 채팅 기능

사용자의 접속상태 표시 기능

다양한 단말 지원. 하나의 계정으로 여러 단말에 동시 접속 지원

푸시 알림

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

이 문제에 대한 훌륭한 답을 도출하기 위해서는 클라이언트와 서버의 통신 방법에 대한 기본적인 지식을 갖추고 있어야만 한다. 채팅 시스템의 경우 클라이언트는 모바일 앱이거나 웹 애플리케이션이다. 클라이언트는 서로 직접 통신하지 않는다. 대신 각 클라이언트는 위에 나열한 모든 기능을 지원하는 채팅 서비스와 통신한다.

가장 기본적인 기능을 생각해보면 다음과 같다.

클라이언트들로부터 메시지 수진

메시지 수신자 결정 및 전달

수신자가 접속 상태가 아닌 경우 접속할 때까지 해당 메시지 보관

채팅을 시작하려는 클라이언트는 네트워크 통신 프로토콜을 사용해 서비스에 접속한다. 따라서 채팅 서비스의 경우 어떤 통신 프로토콜을 사용할 것인가도 중요한 문제다. 대부분 클라리언트/서버 애플리케이션에서 요청을 보내는 것은 클라이언트인데 채팅 시스템도 마찬가지다.

메시지 송신 클라이언트가 이 역할을 한다. 송신 클라이언트는 수신 클라이언트에게 전달할 메시질르 채팅 서비스에 보낼 때, HTTP 프로토콜을 사용한다. 채팅 서비스와의 접속에는 kepp-alive 헤더를 사용하면 효율적인데, 클라이언트와 서버 사이의 연결을 끊지 않고 계속 유지할 수 있어서다. TCP 접속 과정에서 발생하는 핸드셰이크 횟수를 줄일 수 있음은 물론이다. HTTP는 메시지 전송 용도로는 괜찮은 선택이며, 페이스북 같은 많은 대중적 채팅 프로그램이 초기에 HTTP 를 사용했다.

하지만 메시지 수신 시나리오는 이것보다 복잡하다. HTTP는 클라이언트가 연결을 만드는 프로토콜이며, 서버에서 클라이언트로 임의 시점에 메시지를 보내는 데는 쉽게 쓰일 수 없다. 서버가 연결을 만드는 것처럼 동작할 수 있도록 하기 위해 많은 기법에 제안되어 왔는데 폴링(polling), 롱 폴링(long polling), 웹 소켓(WebSocket) 등이 그런 기술이다.

폴링

폴링은 클라이언트가 주기적으로 서버에게 새 메시지가 있느냐고 물어보는 방법이다. 폴링 비용은 폴링을 자주하면 할수록 올라간다. 답해줄 메시지가 없는 경우에는 서버 자원이 불필요하게 낭비된다는 문제가 있다.

롱폴링

롱 폴링의 경우 클라이언트는 새 메시지가 반환되거나 타임아웃 될 때까지 연결을 유지한다. 클라이언트는 새 메시지를 받으면 기존 연결을 종료하고 서버에 새로운 요청을 보내 모든 절차를 다시 시작한다.

메시지를 보내는 클라이언트와 수신하는 클라이언트가 같은 채팅 서버에 접속하게 되지 않을 수 있다. HTTP 서버들은 보통 무상태 서버다. 로드밸런싱을 위해 라운드 로빈 알고리즘을 사용하는 경우, 메시지를 받은 서버는 해당 메시지를 수신할 클라이언트와의 롱 폴링 연결을 가지고 있지 않은 서버일 수 있다.

서버 입장에서는 클라이언트가 연결을 해제했는지 아닌지 알 수 있는 방법이 없다.

여전히 비효율적이다. 메시지를 많이 받지 않는 클라이언트도 타임아웃이 일어날 때마다 주기적으로 서버에 다시 접속할 것이다.

웹소켓

웹소켓은 서버가 클라이언트에게 비동기 메시지를 보낼 때 가장 널리 사용하는 기술이다. 웹 소켓 연결은 클라이언트가 시작한다. 한번 맺어진 연결은 항구적이며 양방향이다. 이 연결은 처음에는 HTTP 연결이지만 특정 핸드셰이크 절차를 거쳐 웹소켓 연결로 업그레이드된다. 일단 연결이 만들어지고 나면 서버는 클라이언트에게 비동기적으로 메시지를 전송할 수 있다. 웹소켓은 일반적으로 방화벽이 있는 환경에서도 잘 동작한다. 80이나 443처럼 HTTP 혹은 HTTPS 프로토콜이 사용하는 기본 포트번호를 그대로 쓴다.

웹소켓을 이용하면 메시지를 보낼 때나 받을 때 동일한 프로토콜을 사용할 수 있으므로 설계뿐 아니라 구현도 단순하고 직관적이다. 유의할 것은 웹소켓 연결은 항구적으로 유지되어야 하기 때문에 서버 측에서 연결 관리를 효율적으로 해야 한다는 것이다.

개략적 설계안

채팅 시스템은 세 부분으로 나누어 볼 수 있다. 무상태 서비스, 상태 유지 서비스, 제 3자 서비스 연동으로 나눠볼 수 있다.

무상태 서비스

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

무상태 서비스는 로드밸런서 뒤에 위치한다. 로드밸런서가 하는 일은 요청을 그 경로에 맞는 서비스로 정확하게 전달하는 것이다. 로드밸런서 뒤에 오는 서비스는 모놀리틱 서비스일 수도 있고 마이크로서비스일 수도 있다. (서비스 탐색, 인증 서비스, 그룹 관리, 사용자 프로파일)

이들 가운데 좀 더 자세히 살펴볼 것은 서비스 탐색 서비스다. 이 서비스는 클라이언트가 접속할 채팅 서버의 DNS 호스트명을 클라이언트에게 알려주는 역할을 한다.

상태 유지 서비스

여기서 유일하게 상태 유지가 필요한 서비스는 채팅 서비스다. 각 클라이언트가 채팅 서버와 독립적인 네트워크 연결을 유지해야 하기 때문이다. 클라이언트는 보통 서버가 살아 있는 한 다른 서버로 연결을 변경하지 않는다. 앞서 설명한 서비스 탐색 서비스는 채팅 서비스와 긴밀히 협력하여 특정 서버에 부하가 몰리지 않도록 한다.

제3자 서비스 연동

채팅 앱에서 가장 중요한 제3자 서비스 푸시 알ㄹ미이다. 새 메시지를 받았다면 설사 앱이 실행 중이 않더라도 알림을 받아야 한다. 따라서 푸시 알림 서비스와 통합은 아주 중요하다.

규모 확장성

설계 중인 시스템의 경우처럼 대량의 트래픽을 처리해야 하는 경우에도 이론적으로 모든 사용자 연결을 최신 클라우드 서버 한대로 처리할 수 있기는 하다. 이때 따져봐야 할 것은 서버 한 대로 얼마나 많은 접속을 동시에 허용할 수 있느냐이다. 이번 장에서 다루는 시스템의 경우 동시 접속자가 1M이라고 가정할 건데, 접속당 10K의 서버 메모리가 필요하다고 보면 10GB 메모리만 있으면 모든 연결을 다 처리할 수 있다.

하지만 모든 것을 서버 한 대에 담은 설계안을 내밀면 면접에서 좋은 점수를 따기 어렵다. 하지만 서버만 한 대 갖는 설계안에서 출발하여 점차로 다듬어 나가는 것은 괜찮다. 유의할 점은 실시간으로 메시지를 주고받기 위해 클라이언트는 채팅 서버와 웹소켓 연결을 끊지 않고 유지한다는 것이다.

채팅 서버는 클라이언트 사이에 메시지를 중계하는 역할을 담당한다.

접속상태 서버는 사용자의 접속 여부를 관리한다.

API 서버는 로그인, 회원가입, 프로파일 변경 등 그 외 나머지 전부를 처리한다.

알림 서버는 푸시 알림을 보낸다.

키-값 저장소에는 채팅 이력을 보관한다. 시스템에 접속한 사용자는 이전 채팅 이력을 전부 보게 된다.

저장소

DB를 어떤 것을 쓸거냐 하는 질문에서 중요하게 따져야 할 부분은 데이터의 유형 과 읽기/쓰기 연산의 패턴 이다.

채팅 시스템이 다루는 데이터는 보통 두 가지다.

첫 번째는 사용자 프로파일, 설정, 친구 목록처럼 일반적인 데이터다. 이런 데이터는 안정성을 보장하는 관계형 데이터베이스에 보관한다. 다중화와 샤딩은 이런 데이터의 가용성과 규모 확장성을 보증하기 위해 보편적으로 사용되는 기술이다.

두 번째 유형의 데이터는 채팅 시스템에 고유한 데이터로, 바로 채팅 이력이다. 이 데이터를 어떻게 보관할지 결정하려면 읽기/쓰기 연산 패턴을 이해해야한다.

채팅 이력 데이터의 양은 엄청나다. 페이스북 메신저나 왓츠앱은 매일 600억 개의 메시지를 처리한다.

이 데이터 가운데 빈번하게 사용되는 것은 주로 최근에 주고 받은 메시지다. 대부분의 사용자는 오래된 메시지는 들여다보지 않는다.

사용자는 대체로 최근에 주고받은 메시지 데이터만 보게 되는 것이 사실이나, 검색 기능을 이용하거나, 특정 사용자가 언급된 메시지를 보거나, 특정 메시지로 점프하거나 하여 무작위적인 데이터 접근을 하게 되는 일도 있다. 데이터 계층은 이런 기능도 지원해야 한다.

1:1채팅 앱의 경우 읽기:쓰기 비율은 대략 1:1 정도다.

이런 요구사항을 만족시키기 위해 본 설계안에서는 키-값 저장소를 추천한다.

키-값 저장소는 수평적 규모확장이 쉽다.

키-값 저장소는 데이터 접근 지연시간이 낮다

관계형 데이터베이스는 데이터 가운데 롱 테일에 해당하는 부분을 잘 처리하지 못하는 경향이 있다. 인덱스가 커지면 데이터에 대한 무작위적 접근을 처리하는 비용이 늘어난다.

이미 많은 안정적인 채팅 시스템이 키-값 저장소를 채택하고 있다. 페이스북 메신저나 디스코드가 그 사례다. 페이스북 메신저는 HBase를 사용하고 있고 디스코드는 카산드라를 이용하고 있다.

데이터 모델

1:1 채팅을 위한 메시지 테이블

message message_id bigint message_from bigint message_to bigint content text created_at timestamp

1:1 채팅을 지원하기 위한 메시지 테이블의 사례다. 이 테이블의 기본 키는 message_id로 메시지 순서를 쉽게 정할 수 있도록 하는 역할도 담당한다. created_at을 사용하여 메시지 순서를 정할 수는 없는데, 서로 다른 두 메시지가 동시에 만들어질 수도 있기 때문이다.

그룹 채팅을 위한 메시지 테이블

group message channel_id bigint message_id bigint message_to bigint content text created_at timestamp

(channel_id, message_id)의 복합키를 기본 키로 사용한다. 여기서 채널은 채팅 그룹과 같은 뜻이다. chennal_id는 파티션 키로도 사용할 것인데, 그룹 채팅에 적용될 모든 질의는 특정 채널을 대상으로 할 것이기 때문이다.

메시지 ID

message_id는 메시지들의 순서도 표현할 수 있어야 한다. 그러기 위해서 다음과 같은 속성을 만족해야 한다.

message_id의 값은 고유해야 한다.

ID 값은 정렬 가능해야 하며 시간 순서와 일치해야 한다. 즉 새로운 iD는 이전 ID보다 큰 값이어야 한다.

RDBMS에서는 auto_increment가 대안이 될 수 있지만 NoSQL은 보통 해당 기능을 제공하지 않는다.

두 번째 방법은 스노플레이크 같은 전역적 64-bit 순서 번호 생성기를 이용하는 것이다.

마지막 방법은 지역적 순서 번호 생성기를 이용하는 것이다. 여기서 지역적이라 함은, ID의 유일성은 같은 그룹 안에서만 보증하면 충분하다는 것이다. 이 방법이 통하는 이유는 메시지 사이의 순서는 같은 채널, 혹은 같은 1:1 채팅 세션 안에서만 유지되면 충분하기 때문이다.

3단계 상세 설계

채팅 시스템의 경우 서비스 탐색, 메시지 전달 흐름, 그리고 사용자 접속 상태를 표시하는 방법 정도가 자세히 살펴볼 만한 부분이다.

서비스 탐색

서비스 탐색의 주된 역할은 클라이어트에게 적절한 채팅 서버를 추가하는 것이다. 여기에는 클라이언트의 위치나, 서버의 용량 등이 영향을 미친다. 그리고 이런 것을 주로 하는 오픈 소스로는 아파치 주키퍼가 있다. 모든 채팅 서버를 등록해놓으면 클라이언트의 요청에 따라 적절하게 서버를 골라준다.

메시지 흐름

채팅 시스템에 있어 종단 간 메시지 흐름을 이해하는 것은 흥미로운 주제다.

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

1. 사용자 A가 채팅 서버 1로 메시지 전송

2. 채팅 서버 1은 ID 생성기를 사용해 해당 메시지의 ID 결정

3. 채팅 서버 1은 해당 메시지를 메시지 동기화 큐로 전송

4. 메시지가 키-값 저장소에 보관됨

5. (a) 사용자 B가 접속 중인 경우 메시지는 사용자 B가 접속 중인 채팅 서버로 전송됨

(b) 사용자 B가 접속 중이 아니라면 푸시 알림 메시지를 푸시 알림 서버로 보냄

6. 채팅 서버2는 메시지를 사용자 B에게 전송, 사용자 B와 채팅 서버 2 사이에는 웹소켓 연결이 있는 상태이므로 그것을 이용

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

여러 단말이 있을 때 각각 채팅 서버와 웹소켓 세션을 맺게 되며 각각의 단말은 cur_max_message_id라는 값을 가진다.

새로운 메시지는 수신자 ID와 현재 로그인한 사용자 ID와 같고 cur_max_message_id보다 큰 ID를 가지는 값이다.

이를 키-값 저장소에 저장한다.

소규모 그룹 채팅

소규모 그룹 채팅에서 사용자 A,B,C가 있다고 생각하면 사용자 A가 B와 C에게 메시지를 보내면 A가 보낸 메시지는 채팅 서버를 통해 B와 C의 메시지 큐로 전송이 된다. 메시지 큐는 메시지 수신함 같은 역할을 한다. 메시지 큐만 확인하면 되니까 동기화 플로가 단순하고 그룹이 크지 않으면 메시지를 수신자별로 복사해서 큐에 넣는 작업의 비용은 그다지 크지 않다.

접속상태 표시

접속상태 서버를 통해 사용자의 상태를 관리한다.

사용자 로그인 부분

클라이언트와 실시간 서비스 사이에 웹 소켓 연결이 맺어지고 나면 접속 상태 서버는 A의 상태와 last_active_at 타임스탬프 값을 키-값 저장소에 보관한다.

로그아웃

사용자가 로그아웃을 하면 API가 접속 상태 서버에 정보를 전달해주고 키-값 저장소에 유저 상태 정보를 offline으로 변경한다.

접속 장애

– 장애에 대응하는 간단한 방법은 장애가 난 사용자를 오프라인으로 표시하고 복구가 되면 온라인으로 다시 표시하는 것이다.

-> 접속이 끊기는 일이 빈번한 경우 이를 계속 반복적으로 적용하는 것은 무리

heartbeat 검사를 통해 문제 해결 가능하다. 이는 온라인 상태의 클라이언트를 확인하기 위해 접속 상태 서버는 클라이언트에서 heartbeat 이벤트를 주기적으로 받고 x초 이내에 받게 되면 온라인 상태로 유지하게 만들 수 있다.

메신저 개발을 위한 NoSQL 데이터 구조

Parse-server 를 기반으로한 메신저를 개발하기 위하여 가장 먼저 데이터 모델링 부터 진행하였다.

Parse-server 는 기본적으로 MongoDB에 데이터를 저장관리하도록 하고 있다. 즉 아래 데이터 모델링은 RDB 가 아니라, NoSQL(MongoDB 같은) 에 저장될 데이터 구조를 정리하여 모델링 한 것이다.

DRAW.IO (https://www.draw.io) 를 통해서 다이어그램을 그리고 이미지 파일 또는 SVG 파일로 Export 할 수 있다.

흰색 오브젝트는 Parse 에서 제공하는 것으로, 상세 필드는 명시하지 않았다.

Follows : User 간의 팔로잉 정보를 저장한다. 메신져에서는 “친구 목록” 을 저장/조회 할 경우 여기에 관리될 것이다.

Channels : 채팅방을 Channel 이라고 명했다. 하나의 채팅방이 Channels 의 하나의 row 가 될 것이다. 여기에는 체널ID 와 사용자 목록을 배열로 가지고 있는다.

Chats : User 별 Channel 목록을 저장하고 있는 오브젝트이다. “채팅 목록” 을 조회 할때 이 오브젝트를 사용한다.

Messages : 체널에서 송수신 되는 메시지가 저장된다.

So you have finished reading the 메신저 db 구조 topic article, if you find this article useful, please share it. Thank you very much. See more: 카카오톡 db 구조, 채팅 DB, 채팅 DB 저장, 웹 메신저 만들기, 카카오 데이터베이스, 메신저 ERD, 친구 목록 ERD, 메신저 동작 원리

Leave a Comment