단일 메시지 브로커 설계
메시지 순서 유지
- 메시지는 발생 순서에 맞게 서비스에 도착해야 함
- 중복 처리 되지 않아야 함
- 스케일 아웃(서비스 인스턴스 3개)가 동일한 메시지 채널을 구독
- 송신자가 주문 생성, 주문 수정, 주문 취소를 순서대로 게시
- 네트워크 지연, 가비지 컬렉션 등 여러가지 사유로 인해 → 순서대로 처리되지 않을 수 있음
샤드 채널(Sharded channel, partitioned Channel)
- 하나의 샤드 채널은 2개 이상의 샤드로 구성
- 송신자(sender)는 메시지 헤더에 임의의 문자열, 바이트 시퀀스를 사용한 샤드 키 명시
- 메시지 브로커는 이 샤드 키 → 특정 샤드, 파티션에 할당
Kafka와 Zookeeper의 관계
- Kafka는 소비자 그룹(복수의 수신자 인스턴스를 하나로 묶어 동일한 수신자로 취급) 하여, 하나의 수신자에게 할당
- 특정 주문 이벤트 → 동일한 샤드에 게시되고 동일한 메시지 소비자에 의해 처리
중복 메시지 처리
문제점
클라이언트가 메시지를 처리하고 데이터베이스를 업데이트하였으나, 수신 확인 신호를 보내기 전 문제 발생 → 메시지 브로커는 수신확인 받지 못하여, 동일한 메시지 다시 전달
멱등성을 가지는 메시지 핸들러
- 연산을 여러번 적용해도 결과가 달라지지 않는 성질: 멱등성
- 메시지 핸들러가 멱등성을 가지면 → 시스템 장애로 인한 이벤트 중복이 발생하더라도 결과적으로 동일 상태가 된다
메시지 추적하여 중복 메시지 제거
이미 처리된 메시지 아이디를 데이터 베이스에 저장 → DB와 비교하여 신규 메시지인 경우 처리, 중복 메시지인 경우 제거해야 함.
트랙잭셔널(Transactional) 메시징
- 서비스는 데이터베이스 업데이트와 메시지 전송이 하나의 트랜잭션 안에서 원자적으로 실행되어야 함 → otherwise, DB가 저장되지 않고 메시지 전달, DB 저장되었지만 메시지 전달 X 에러 발생
트랜잭션 아웃박스 패턴
- 메시지 전송 주문 서비스가 주문 객체를 생성, 수정, 삭제함 동시에 OUTBOX라는 데이터베이스 테이블에 저장함
- 메시지 중계기가 아웃박스 테이블에서 메시지를 읽어 메시지 브로커로 전달, 객체 수정, 메시지 저장은 RDBMS(ACID 트랜잭션)이기 때문에 원자성 보장
폴링 퍼블리셔 패턴
- RDBMS 사용시, 아웃박스 테이블에 삽입된 메시지를 게시하는 가장 간단한 방법
- 메시지 중계기 → 아웃박스 테이블을 주기적으로 폴링하여 게시되지 않은 메시지 찾은 후 → 메시지 브로커에 게시, 아웃박스 테이블에서 삭제
- NoSQL에선 사용 불가
트랙잭션 로그 테일링 패턴을 적용하여 이벤트 게시하기
- 데이터베이스 트랙잭션 로그를 추적(트랜잭션 로그 수집기)가 트랜잭션 로그를 읽어서 모든 변화를 메시지 브로커에 메시지 게시
- 가장 많이 쓰는 패턴
비동기 메시징을 통한 가용성
- 동기식 통신 → 애플리케이션의 가용성을 감소 시킴
- 동기식 통신보다 비동기 메시징 이용 지향
데이터 복제하기
- 서비스는 요청을 처리하기 위한 데이터 복제본을 만들고 → 복제본을 최신 상태로 유지
- 데이터의 양이 과도하게 커지면 비효율, 원본 데이터 수정시 해결 X
응답 우선 회신 후 잔여 작업 처리
- 클라이언트의 요청을 받아서 → 먼저 로컬에서 사용 가능한 데이터로 요청 처리, 그 결과 응답 클라이언트에게 회신 → 비동기 방식으로 다른 서비스에게 메시지 전송하여 후속 프로세스 진행
예) 주문 서비스 → 주문 생성 요청 처리할 때, 최소한 정보로 검증 → 그 후 다른 서비스에게 요청하여 주문 생성 요청 검증
→ 연관 서비스 다운 되더라도 운영 가능 (큐에 처리 과정을 쌓아서 오류 복구후 순차 실행)
→ 주문 검증에 대해 최소한의 보장만 하므로, 정상 생성위해 주기적 폴링 해야 함.
헤더/바디에 어떤 내용?
- 메시지의 비지니스 로직: Sender의 포트를 통해 Sender 호출 → 채널에 메시지 배포, 메시지 핸들러는 메시지 채널에서 메시지 읽어와 수신 포트를 통해 전달.
헤더: 본문 데이터를 설명하는 명칭:값 형식으로 된 메타 데이터 집합, 메시지 아이디와 응답을 수신할 메시지 채널
본문: 텍스트, 바이너리 포맷
메시지
- 문서 - 데이터만 포함된 메시지로, 커맨드에 대한 응답으로 회신되는 메시지
- 커맨드 - 호출할 오퍼레이션, 매개변수 명시
- 이벤트: 송신자에게 유의미한 상태 변화 발생했다는 것을 알려주는 메시지 (주문, 고객 같은 도메인 객체의 상태 변경이 발생했다는것을 알려줌)
사용자 멘션은 어떻게?
- 점대점 방식(Point-to-Point) 방식을 사용함.
단방향 알림
- 클라이언트가 점대점 채널로 커맨드 메시지 보내면 → 해당 채널 소유하는 서비스가 구독해서 처리하는 방식. 단방향이므로 메시지에 대한 응답 X
첨부파일, 바디에 어떻게 들어가야 할지?
- 클라이언트가 점대점 채널로 메시지 보내면 → 해당 채널 소유하는 서비스가 구독해서 처리하는 방식. 단방향이므로 메시지에 대한 응답 X
- 헤더: 단순 메시지 id, 수신 메시지 채널
- 바디: Content-Type: multipart/form-data로 하면 되지 않을까?
'책 > 가상 면접 사례로 배우는 대규모 시스템 설계 기초 정리' 카테고리의 다른 글
단일 메세지 모델 설계 하기(kafka + STOMP + Cassandra) (2) | 2024.01.03 |
---|---|
[가상면접 사례로 배우는 대규모 시스템 설계 기초] Chap3. 시스템 설계 공략법 (0) | 2023.11.29 |
[가상면접 사례로 배우는 대규모 시스템 설계 기초] Chap2. 개략적인 규모 추정 (0) | 2023.11.29 |
[가상면접 사례로 배우는 대규모 시스템 설계 기초] Chap12. 채팅 시스템 (1) | 2023.11.24 |
[가상면접 사례로 배우는 대규모 시스템 설계 기초] Chap01. 사용자 수에 따른 규모 확장성 (0) | 2023.11.16 |