# 채팅 시스템

### 요구사항 (Software Requirement)

- 텍스트만 지원하는 일대일 또는 그룹 채팅 서비스

- DAU(Daily Active User) = 5천만

- 그룹 채팅의 경우 최대 100명까지 수용

- 사용자 접속 상태 표시

- 메시지 길이 제한 = 100,000자

- E2E 암호화는 차후 논의

- 채팅 보관 기간 = 무제한

- 푸시 알림

- 하나의 계정으로 여러 단말에 동시 접속 지원

### 기본 기능

- 클라이언트로부터 메시지 수신

- 메시지 수신자 결정 및 전달

- 수신자가 접속(online) 상태가 아닌 경우에는 접속할 때까지 해당 메시지 보관

## 통신 기술

### HTTP

가장 일반적인 프로토콜. 채팅 서비스에서는 keep-alive 헤더를 사용해서 클라이언트와 서버 사이의 연결을 끊지 않고 유지한다. 그렇지만 임의의 시점에 메시지를 보내기에는 비용이 많이 든다.

### 폴링

- 클라이언트가 주기적으로 서버에게 새 메시지가 있냐고 물어본다.

- 폴링을 자주하면 불필요한 트래픽이 많이 발생

### 롱 폴링

- 클라이언트가 요청을 보내고, 새 메시지를 받거나 타임아웃 될 때까지 연결을 유지한다. 

- 하지만 클라이언트가 서버를 계속 물고 있기 때문에 다른 클라이언트가 접근할 수 없는 상황이 생길 수 있다. 또한 서버 다중화가 쉽지 않다. 

### 웹소켓

웹소켓 연결은 일반적인 비동기 메시지 기술이다. 

- HTTP로 처음 연결해서 웹소켓으로 바꿔탐

- 80, 443 포트를 쓰기 때문에 방화벽이 있는 환경에서도 잘 동작

- 양방향 메시지 전송이 가능하다.

## 개략적인 설계안

### 무상태(stateless) 서비스

로드밸런서 뒤에 서비스를 둬서 단일 진입점으로 두면 편하다. 서비스들을 동적으로 탐색하기 위해서 service discovery를 둠

### 상태 유지(stateful) 서비스

서비스 탐색을 잘 사용해서 서버의 부하를 관리한다.

For the site tree, see the [root Markdown](https://slashpage.com/kaonmir.md).
