책의 내용을 일부 ‘발췌’해서 정리 각 장별 간단한 개요는 작성하지만, 실질적으로는 내가 조금 더 기억하고 싶은 내용만 일부 발췌해서 기록
1장 사용자 수에 따른 규모 확장성
개요
- 기본적인 어플리케이션 설게와 매우 자주 사용되는 컴포넌트 혹은 구현해야하는 요구사항에 대해서 소개해 주는장
- 예를들어 아래와 같은 것들을 개념을 개략적으로 설명해준다.
- 데이터 저장소
- 수직적 확장,수평적 확장
- 다중화
- 캐시
- 안정성과, 가용성과같은 시스템을 측정할 수 있는 요소들도 설명해준다.
내용
- 캐시 사용시 유의 할 점
- 어떤 상황에 바람직한지 생각하기
- 어떤 데이터를 캐시할지 생각하지
- 만료기한을 잘 설정하기
- 일관성을 유지 할 수 있도록 생각하기
- 저장소의 원본을 갱신하는 연산과 캐시를 갱신하는 연산이 단일 트랜잭션으로 처리되지 않는 경우?
- 캐시가 단일 장애 지점이 되지 않도록 설계하기
- 캐시 메모리의 용량과 방출 정책에 대해서 설계하기
- 샤딩
- “같은 스키마를 쓰지만 샤드에 보관되는 데이터 사이에는 중복이 없다.”
- 쓰기와 읽기 모든 부하에 대한 분산이 가장 큰 장점
- 데이터 베이스의 수평적 확장(샤딩) 이후에 생겨나는 문제점
- 데이터의 재 샤딩이 필요해짐 (샤드 소진)
- 유명인사 문제 : 특정 샤드에 질의가 집중되는 문제
- 조인과 비정규화
정리
- 웹 계층은 무상태 계층으로
- 모든 계층에 다중화 도입
- 가능한 한 많은 데이터를 캐시할 것
- 여러 데이터 센터를 지원할 것
- 정적 콘텐츠는 CDN을 통해 서비스할 것
- 데이터 계층은 샤딩을 통해 그 규모를 확장할 것
- 각 계층은 독립적 서비스로 분할할 것
- 시스템을 지속적으로 모니터링하고, 자동화 도구들을 활용할 것
2장 개략적인 규모 추정
개요
- 이후에 설명할 내용이나, 설계에 있어 근거가 되는 ‘단위’를 설명해주는 장
- 데이터의 단위나 속도등을 알려준다.
제프딘의 응답 지연시간
| 작업 | 소요 시간 |
|---|---|
| L1 캐시 참조 | 0.5 ns |
| 분기 예측 오류 | 5 ns |
| L2 캐시 참조 | 7 ns |
| 뮤텍스 락/언락 | 100 ns |
| 메인 메모리 참조 | 100 ns |
| 압축(Zippy)로 1KB 압축 | 10,000 ns (10 μs) |
| SSD에서 4K 읽기 | 16,000 ns (16 μs) |
| 메모리에서 1MB 순차적 읽기 | 250,000 ns (250 μs) |
| SSD에서 1MB 순차적 읽기 | 1,000,000 ns (1 ms) |
| 하드 디스크 탐색 | 10,000,000 ns (10 ms) |
| 하드 디스크에서 1MB 순차적 읽기 | 20,000,000 ns (20 ms) |
| 같은 데이터센터 내 서버 간 왕복 | 500,000 ns (0.5 ms) |
| 미국 해안 간 왕복 지연시간 | 30,000,000 ns (30 ms) |
| TCP 패킷 재전송 | 1-3 초 (1,000,000,000-3,000,000,000 ns) |
| 디스크 드라이브 MTBF(평균 고장 간격) | 수개월 (10^15 ns) |
- 가용성 관련 : 99%가 연간 3.65일의 downtime을 허용한다.
- qps : qury per second 추정치
- mau x 매일 사용하는 사용자 비율 x 각사용자의 평균 트윗을 올리는 건수 : 이런식으로 계산
- 즉 mau가 얼마인지,
- 실제 사용 비율을 얼마로 추정하는지,
- 미디어를 포함한 요청이 얼마나될지
- 미디어 데이터터 평균값은 얼마나 될지
- 데이터 보존 기한은 얼마일지
- 위와 같은 질문과 함께 따져봐야한다.
3장 시스템 설계 면접 공략법
개요
- 설계 면접과 관련한 실질적인 팁
- 너무 부담가지지 말것
- 완벽한 설계를 보려는게 아님
- 설계 기술의 시연과 과정에서 내린 결정들에 대한 방어 능력을 보이는자리
- 부정적 신호에만 유의할것
- 설계의 순수성에 집착하지 말고 tradeoff를 잘 고려할 것
효과적인 면접을 위한 4단계 접근법
1단계 문제 이해 및 설계 범위 확정
- 요구사항을 완전히 이해하지 않고 생각 없이 답내지 않기 (속도를 늦춰라)
- 요구사항을 정확하게 이해하는데 ‘필요한’ 질문을 하라.
- 아래는 도움이 될 질문 예시
- 구체적으로 어떤 기능들을 만들어야 하나?
- 제품 사용자 수는 얼마나 되나?
- 회사의 규모는 얼마나 빨리 커지리라 예상하나? 석 달, 여섯 달, 일년 뒤의 규모는 얼마가 되리라 예상하는가?
- 회사가 주로 사용하는 기술 스택(technology stack)은 무엇인가? 설계를 단순화하기 위해 활용할 수 있는 기존 서비스로는 어떤 것들이 있는가?
2단계 개략적인 설계안 제시 및 동의 구하기
3단계 상세 설계
4단계 마무리
- 개선점, 병목, 혹은 더 개선하능한 구간을 질문받으면 같이 고민해본다.
- 요약을 제시한다.
- 오류가 발생하면 무슨일이 생기는지 땁져본다.
- 운영이슈도 논의해본다.
- 미래에 닥칠 규모 확장 요구에 어떻게 대처할 것인지 생각해본다.
4장 처리율 제한 장치의 설계
개요
- 처리율 제한 장치 설계 예시를 통한 면접 가이드
- 사실 처리율 제한 장치를 이해하는데도 큰 도움이 되는 장
처리율 제한 장치에 대한 이해
- 클라이언트 혹은 서비스가 보내는 트래픽의 처리율을 제어하기 위한 장치
- 임계치에 도달하면 추가로 도달한 모든 호출은 처리가 중단 되어야 한다.
- 장점
- ddos와 같은 공격에 의한 자원 고갈을 방지
- 비용을 절감
- 과부하를 막아준다.
1단계 문제 이해 및 설계 범위 확정
- 서버측 api 처리율을 제한하기 위한 장치를 설계해야함
- 다양한 제어 규칙을 정의 할 수 있어야함.
- 대규모 요청을 처리해야함
- 분산 환경에 동작해야함.
- 독립된 서비스여도 상관 없고, 애플리케이션 코드에 포함되어도 상관 없음.
- 사용자에게 전달되는 에러처리를 해야함
2단계 개략적 설계안 제시 및 동의 구하기
- 클라이언트를 배제하면 두가지가 있다. (위변조가능, 통제어려움)
- 서버측
- 처리율 제한 미들웨어 : 보통 msa환경에서는 api 게이트웨이에 많이 둔다.
개인적인 의견으로는 관리포인트가 늘어나지 않는게 낫다는 관점에서 게이트웨이가 좋은 것 같다. 추후 상용 게이트웨이를 쓰거나 할 니즈가 생기는경우도 생각해보기 쉽다.
처리율 제한 알고리즘
- 토큰 버킷 알고리즘
- 간단하고, 이해도도 높고, 많이쓰인다.
- 간단하게 요청이 도착하면, 토큰 버킷을 검사해서 토큰이 남아있는지 확인하고 없으면 요청을 버린다.
- 버킷에 토큰을 공급하는 공급률을 조정한다.
- 버킷크기와 토큰 공급률을 인자로 한다.
- 통상적으로 api endpoint별로 별도의 버킷을 둔다.
- 메모리 효율적이고, 구현이 쉽고, 짧은 시간에 집중되는 (burst)트래픽도 처리 가능하다.
- 누출 버킷 알고리즘 (leaky bucket)
- 버킷을 큐로 구현하면 아이디어가 비슷하다.
- 토큰의 공급이 아닌, 큐의 빈자리를 기준으로 요청을 버린다.
- 큐의 크기가 제한되어 마찬가지로 메모리 효율적이다.
- 고정된 처리율을 가지고 있어 안정적 출력이 필요한 경우 적합하다.
- 단기간 트래픽을 제때 처리 못하면, 최신 요청들이 버려진다.
- 고정 윈도 카운터 알고리즘
- 이후 사용될 이 아이디어를 기반으로한 다른 개선버전이 실질적으로 쓰인다.
- 타임라인을 고정된 간격의 윈도우로 나누고 그 윈도우마다 카운터를 붙인다.
- 윈도우 내에 카운터만큼의 요청이 가득차면 다음 윈도우가 열릴때까지 버린다.
- 경계구간에 몰리면 허용한도 이상의 요청을 받게 될 수 있다.
- 이동 윈도 로깅 알고리즘
- 요청의 타임스탬프를 추적한다.
- 타임스탬프를 sorted set 같은것에 보관한다.
- 새 요청이 오면 만료된 타임스탬프는 제거된다. (현재 윈도우의 시작 지점보다 오래된 타임스탬프)
- 새요청의 타임스탬프를 로그에 추가한다.
- 로그의 크기가 허용치보다 같거나 작으면 요청을 시스템에 전달한다. 아니면 버린다.
이게 이해가 조금 힘들었는데, 타임스탬프가 새로운 요청 기준으로 판별된다는 점을 추가하면 이해가 쉽다. 즉 새로운 요청이 왔을 때, 그 시점으로 윈도우시간 이전의 로그 카운트를 검사한다.
- 위의 하나를 골라서 상세 설계에 들어간다.
3단계 상세 설계
- 처리율 제한 규칙을 고려한다.
- 처리율 한도 초과 트래픽의 처리 : 적절한 헤더 응답과 함께 내보내준다.
5장 안정 해시 설계
개요
- 수평적 규모 확장성을 달성하기 위해서는 요청 또는 데이터를 서버에 균등하게 나누는 것이 중요하다.
- 해시 키 재배치 문제
- 일반적으로 모듈러연산을 기준으로 해시한 상황을 가정하면,
- 서버풀의 크기가 고정되어 있을 때, 그리고 데이터 분포가 균등할때는 잘 동작한다.
- 하지만 서버가 추가되거나 기존 서버가 삭제되면 문제가 생긴다.
- 예를 들어 n번 서버가 장애를 일으켜 동작을 중단하면 서버풀이 n-1개가 되는데 그 결과로 해시값은 변하지 않지만 나버지 연사을 적용하여 계산한 서버 인덱스 값은 달라질 것이다.
- 문제는 이러면 죽은 서버 뿐만이 아니라 다른 서버의 키도 재분배가 이루어져아 한다.
- 안정해시
- 안정해시는 해시 테이블의 크기가 조정될 때 오직 k/n개의 키만 재배치하는 해시 기술이라고 한다.
- 여기서 k는 키의 갯수이고 n이 슬롯의 갯수이다.
- 원리는 해시 함수를 기반으로 해시 공간(해시함수의 y값 공간)을 두고, 순환 구조를 만든다.
- x0 ~ xn 까지의 해시공간이 있을 때 xn다음이 x0가 되는 구조
- 그 키의 링(ring) 위에 서버와 키들을 배치하고, 특장 방향으로 돌면서 특정 키값마다 저장할 서버를 찾는구조
- 균등분포와 파티션 크기를 일정하게 유지하기 어렵다는것이 단점이었다.
- 어차피 논리적인 공간이므로, 가상노드를 여러개를 두어 해결한다.
6장 키-값 저장소 설계
1단계 문제 이해 및 설계 범위 확정
- 키값 쌍의 크기는 10kb이하.
- 큰 데이터를 저장 할 수 있어야 한다.
- 높은 가용성을 제공해야한다.
- 높은 규모의 확장성을 제공해야한다.
- 데이터 일관성 수준은 조정이 가능해야 한다.
- 응답 지연시간이 짧아야 한다.
분산 키-값 저장소
- 분산 해시테이블
- 분산 시스템을 설계할때는 CAP정리를 이해하고 있어야 한다.
- Consitency vs Availability vs Partition toleration
- Consitency : 일관성, 즉 모든 클라이언트는 어떤 노드에 접근하든 ‘같은’ 데이터를 봐야한다.
- Availability : 가용성, 즉 모든 클라이언트는 일부 노드에 장애가 발생해도 ‘항상’ 응답을 받아야 한다.
- Partition toleration : 파티션 감내, 즉 두 노드의 네트워크 파티션이 생기더라도 시스템은 계속 동작해야 한다.
요점은 이 세가지중에 두가지를 충족하려면 나머지 하나는 버려야한다.
- CP 시스템 : 일관성과 파티션 감내를 충족한다. 즉 가용성을 버린다.
- Two Phase Commit에서
- 네트워크 분할 발생 시, 트랜잭션 조정자가 모든 참여 노드로부터 응답을 받지 못하면 전체 트랜잭션을 중단한다.
- 이 과정에서 일부 노드가 사용 불가능해지더라도 데이터 일관성을 유지한다.
- Mongodb 예시
- 예를들어 네트워크 분할 발생시 슬레이브 노드는 통신이 끊기면 그냥 읽기요청을 처리안해버림
- Two Phase Commit에서
- AP 시스템 : 가용성과 파티션 감내를 충족한다. 즉 일관성을 버린다.
- 네트워크 분할에도, 쓰기와 읽기 작업을 계속 처리한다.
- 최종적 일관성을 제공하기위해서 보완수단을 쓴다. (즉각적인 일관성을 희생)
- CA 시스템 : 가용성과 일관성을 충족하지만, 네트워크 파티션을 희생한다.
- 단일 노드로 구성할경우 (말장난 같지만)
- 실질적으로는 없고, 사용도 안하는 구조
결론적으로는 CP냐 AP냐의 트레이드 오프 사이에서 결정하는 경우가 압도적 대다수
다시 분산 키-값 저장소에서 달성해야 할 목표들
- 데이터 파티션 : 안정해시를 이용해서 파티션한다.
- 데이터 다중화 : 안정해시 위에서 저장될 파티션을 정하는 로직에서 추가적으로 n개의 노드를 더 탐색해서 다중화한다.
- 데이터 일관성 : 정족수 합의 프로토콜을 이용한다.
- 정족수 합의 프로토콜
- 일단 기본적으로 다음과 같은 변수를 사용한다.
- N = 사본의 갯수
- W = 쓰기 연산 정족수, 즉 쓰기 연산이 성공한것으로 간주되려면, W개의 서버로부터 응답을 받아야 한다.
- R = 읽기 연산 정족수, 마찬가지로 R개의 서버로부터 동일한 값을 응답받아야 정상적인 읽기로 간주한다.
- 보통 많이 사용하는 구성
- R = 1, W = N : 빠른 읽기 연산에 최적화
- W = 1, R = N : 빠른 쓰기 연산에 최적화
- W + R > N : 강한 일관성 (보통 N = 3, W = R = 2 의 비율)
- W + R <= N : 강산 일관성이 보장되지 않음
- 일단 기본적으로 다음과 같은 변수를 사용한다.
- 일관성 모델 :
- 강한 일관성 : 클라이언트는 절대 낡은 데이터를 보지 못하게 한다.
- 약한 일관성 : 읽기 연산은 가장 최근에 갱신된 결과를 반환하지 못할 수 있다.
- 최종 일관성 : 약한 일관성이지만, 최종적으로는 동기화 된다.
- 보통 강한 일관성은 분산환경에서는 맞지 않다. 읽기 락까지 걸어버리기 때문에
- 비 일관성 모델 :
- versionning과 vector clock을 주로 많이 사용한다.
- 충돌 감지 및 해소 과정
- 초기 설정
- 시스템의 각 노드는 자신만의 벡터 시계를 유지한다.
- 벡터 시계는
[node1: count1, node2: count2, ...]형태로 표현한다. - 초기값은 모든 노드에 대해 0으로 설정한다.
- 데이터 변경 시
- 노드가 데이터를 변경할 때마다 자신의 카운터를 증가시킨다.
- 변경된 데이터는 현재 벡터 시계 값과 함께 저장한다.
- 데이터 동기화 과정
- 노드 간에 데이터를 동기화할 때, 데이터와 함께 벡터 시계를 전송한다.
- 수신 노드는 자신의 벡터 시계와 수신된 벡터 시계를 비교한다.
- 충돌 감지
- 벡터 시계 간의 관계는 세 가지로 분류한다.:
- 동일(Equal): 두 벡터의 모든 값이 같은 경우.
- 선행(Happens-before): 벡터 A의 모든 값이 벡터 B의 값보다 작거나 같고, 적어도 하나는 작은 경우.
- 동시성(Concurrent): 위 두 관계가 성립하지 않는 경우. (일부 값은 더 크고, 일부 값은 더 작음)
- 충돌은 두 벡터 시계가 동시성 관계일 때 감지. 이는 두 노드가 서로의 변경사항을 모른 채 동일한 데이터를 변경했음을 의미하기 때문.
- 벡터 시계 간의 관계는 세 가지로 분류한다.:
- 충돌 해소 방법
- 자동 해소:
- 타임스탬프 기반: 가장 최근 타임스탬프를 가진 버전을 선택.
- 우선순위 기반: 미리 정의된 노드 우선순위에 따라 선택.
- 사용자 개입:
- 충돌 발생 시 사용자에게 알리고 수동 병합을 요청.
- 두 버전의 차이점을 표시하여 사용자가 선택하도록.
- 병합 전략:
- 필드별 병합: 객체의 각 필드를 독립적으로 처리.
- 의미적 병합: 애플리케이션 로직에 기반한 병합 규칙을 적용.
- 자동 해소:
- 벡터 시계 업데이트
- 충돌이 해소된 후, 노드는 자신의 벡터 시계를 업데이트:
- 자신의 카운터를 증가.
- 다른 노드의 카운터는 수신된 벡터 시계와 자신의 벡터 시계 중 더 큰 값을 취함.
- 충돌이 해소된 후, 노드는 자신의 벡터 시계를 업데이트:
- 초기 설정
- 장애 감지 :
- 멀티캐스팅은 서버가 많으면 비효율적임
- 그래서 가십 프로토콜같은 솔루션을 사용
- 각자 노드가 테이블을 가지고 있으며 무작위로 하트비트를 전송/기록
- 특정 노드의 하트비트 시간이 지연되었으면 다른노드로 전달
- 다른 노드에서도 오랫동안 증가가 안되어있으면 장애 노드로 파악
- 일시적 장애 처리 :
- 엄격한 정족수에서는 그냥 연산금지로 끝남
- 느슨한 정족수는 해시링을 이용해서 대응할 서버를 이동시킴
- 그동안의 변경사항을 일괄 반영하는 장치를 만들어둬야함
- 영구 장애 처리 :
- 반 앤트로피 프로토콜을 구현해서 사본을 동기화해야함
- 머클트리를 이용한다고 함
7장 분산 시스템을 위한 유일 id 생성기 설계
1단계 문제 이해 및 설계 범위 확정
- 유일, 정렬가능
- 숫자로만 구성
- 64bit로 표현가능
- 발급 날짜에 따라 정렬되어야함
- 초당 10,000개를 만들 수 있어야 함
2단계 개략적 설계안 제시 및 동의 구하기
- multi master replication
- uuid
- ticket server
- snowflake
multi master replication
- db마다 autoincrement를 db 숫자만큼 하기
- 단점이 너무 많다 대표적으로 확장성
uuid
- 충돌 가능성이 낮다
- 중복이 발생할 기댓값이 50%가 되려면 초당 10억개씩 100년동안 생성..
- 서버간 조율이 전혀 필요없음
- 근데, 128비트에 문자열도 포함되고 시간순 정렬이 불가능하다.
ticket server
- 하나의 auto increment 서버를 둔다.
- 유일성이 보장되는데 구현도 쉽다.
- SPOF
snowflake
- 트위터에서 만들었다고 함
- 사인, 타임스탬프, 데이터센터 id, 서버 id, 일련번호
- 기본적으로 타임스탬프 포함이라 정렬이됨
- 용량이 적음
- 같은 노드에서 시간이 겹치는 경우에만 일련번호로 분리
8장 URL 단축기 설계
1단계 문제 이해 및 설계 범위 확정
- 쓰기연산 : 매일 1억개
- 초당쓰기 : 1160개
- 읽기연산 : 비율을 10:1로 가정 초당 11600개
- 10년운영시 레코드 : 3650억개
- 보통 36.5tb
2단계 개략적 설계안 제시 및 동의 구하기
- 기본적으로 예상 가능한 구조
- 리다이렉션은 301, 302를 고려해야함
- 301은 영원히 리다이렉트를 함 (브라우저에서)
- 302는 계속 우리서버를 프록시할것
- 특정 메타데이터를 이용할 서비스를 고려중이라면 302
- URL 단축 로직
- 해시로직이 필요함
- 해시 후 충돌 해소
- 처음 7개 글자만 이용
- 당연히 발생할 충돌은 특정 문자를 더 붙이고 다시 검사
- 충돌이 많은 상황이라면 db조회가 많아질 수 있음
- base-62 변환
- 캐시로 최적화
9장 웹 크롤러 설계
- 는 정리는 생략..
10장 알림 시스템 설계
- 푸시, sms, 이메일 지원
- soft real-time 시스템 (가능한 빨리, 부하시 약간의 지연을 허용)
- ios, android, 랩톱/데스크톱
- 알림은 클라이언트앱쪽에서, 혹은 스케줄링 서버를 통해
- 알림을 안받는 설정도 가능하도록
- 하루에 천만건의 모바일 푸시 알림, 백만건의 sms, 500만건의 이메일
알림 유형별 지원 방안
ios
- apns가 있음
- device token, payload를 저기에 보내면 됨
android
- 마찬가지
sms
- 상용 서비스 이용 필요
이메일
- 마찬가지로 벤더를 끼고 함
2단계 계락적 설계안 제시 후 동의 구하기
- 기본적으로 병목을 고려해야하고
- spof가 안되도록 해야함
- 규모확장성을 갖춰야함
- 위의 것들을 고려하면 큐를 이용한 서버를 생각하게됨
- 다중화 가능한 알림서버와 데이터베이스
- 각 서비스별 큐를 두고 작업서버를 연동
3단계 상세 설계
안정성
- 데이터 손실 방지 : 재시도 매커니즘을 구현하기 위해 알림 로그 데이터베이스를 유지
- 알림 중복 전송 방지 : 중복 전송을 100퍼센트 막는것은 사실상 불가능하다.
추가로 필요한 컴포넌트 및 고려사항
- 알림 템플릿
- 알림 설정 : 사용자별로 알림 설정
- 전송률 제한
- 재시도 방법
- 푸시알림과 보안
- 큐 모니터링
- 이벤트 추적
11장 뉴스 피드 시스템 설계
-
이건 데이터 중심 애플리케이션 설계에서 다룬 내용이 주 맥락이다.
-
기본적으로 뉴스피드 캐시를 사용자마다 두는 구조로 개발을 하는데,
-
쓰기 대비 읽기 트래픽이 압도적인 뉴스피드 특성상,
-
읽기 최적화를 위해서 쓰기 시점 팬아웃을 한다.
-
즉 내가 포스팅을 하면 나랑 친구 혹은 follow하는 사용자들의 피드 캐시에 쓰기가 된다는것.
-
그러면 그 캐시를 받아서 읽기 성능이 비약적으로 상승한다.
-
qps분석 결과 읽기 트래픽이 압도적으로 많아 쓰기 성능이 떨어지는것을 감내하고 의사결정을 한것
-
그러나 호날두가 등장한다!
-
호날두는 팔로워가 몇억명인데
-
호날두의 쓰기속도가 매우 줄어든다.
-
그래서 하이브리드로 특정 팔로워 이상은 쓰기 팬아웃을 안한다는 것
-
추가적으로 책에서 언급된건
- 쓰기 시점의 팬아웃은 서비스를 자주 이용하지 않는 사용자도 갱신하는것
- 그로인해 비활성화된 사용자가 많다면 읽기시점에 팬아웃하는 모델이 유리할수 있따는것
-
그리고 캐시와 관련된 전략이 나와있다.
12장 채팅 시스템 설계
1단계 문제 이해 및 설계 범위 확정
- 응답 지연이 낮은 일대일 채팅
- 최대 100명까지 그룹채팅
- 사용자의 접속상태 표시 기능
- 다양한단말지원
- 푸시알림
2단계 개략적 설계안 제시 및 동의 구하기
- 중간에 서버를 둔다는것을 이해해야 한다.(클라이언트간 통신이 아님)
- 결론적으로 우리 서버는
- 클라이언트들로부터 메시지 수신
- 메시지 수신자 결정 및 전달
- 수신자가 접속상태가 아닌경우 접속할 때 까지 메시지 보관
폴링
- 클라이언트가 주기적으로 서버에 데이터를 요청하는것
- 롱 폴링 : 폴링의 비효율을 일부 해소한 것.
- 폴링중 세 메세지가 없는경우 타임아웃만큼만 대기한다.
- 서버측에서 마찬가지로 연결 여부를 체크할 방법이 없다.
웹소켓
- 서버가 클라이언트에게 비동기 메세지를 보낼때 사용
- http 핸드쉐이크 이후 웹소켓으로 업그레이드함
- 서버 입장에서 관리만 효율적으로 해주면 됨
2단계 계략적 설계안 제시 및 동의 구하기
- 일단 기본적으로 무상태로 설계하지만, 채팅서비스는 무상태로 설계할 수 없음
- 규모 확장성 : 간단한 계산 (메모리 정도) 이후 양해구해서 넘어가기