공개: KoTalk 최신 기준선
This commit is contained in:
commit
debf62f76e
572 changed files with 41689 additions and 0 deletions
515
docs/archive/planning/01-backend-platform-architecture.md
Normal file
515
docs/archive/planning/01-backend-platform-architecture.md
Normal file
|
|
@ -0,0 +1,515 @@
|
|||
# 개인 메신저 프로젝트 백엔드/플랫폼 아키텍처 합의안
|
||||
|
||||
이 문서는 기존 Rocky Linux VPS 위에 Docker로 채팅 서버를 구축하는 것을 전제로 한 구현 지향형 백엔드/플랫폼 설계안이다. 목표는 카카오톡 PC 버전 수준의 빠른 체감 응답성과 안정적인 실시간 동기화 경험을 내는 것이다.
|
||||
|
||||
합의에 참여한 전문 관점:
|
||||
|
||||
- 리얼타임 백엔드 아키텍트
|
||||
- 플랫폼 엔지니어
|
||||
- PostgreSQL 데이터 엔지니어
|
||||
- SRE/관측성 엔지니어
|
||||
- 보안 엔지니어
|
||||
- 스토리지/백업 엔지니어
|
||||
|
||||
## 1. 전제와 설계 원칙
|
||||
|
||||
전제:
|
||||
|
||||
- 서버는 기존 Rocky Linux VPS에 배포한다.
|
||||
- Docker 사용 가능하다.
|
||||
- 초기 개발 대상은 Windows PC 클라이언트다.
|
||||
- 초기는 개인 사이드 프로젝트지만, 구조는 다중 디바이스와 사용자 증가를 막지 않아야 한다.
|
||||
|
||||
설계 원칙:
|
||||
|
||||
- 초기에는 단일 VPS에 맞는 단순성을 우선한다.
|
||||
- 그러나 프로토콜, 데이터 모델, 메시지 ID, 스토리지 인터페이스는 이후 수평 확장을 막지 않게 설계한다.
|
||||
- 채팅 메시지의 원본 저장소는 처음부터 PostgreSQL로 통일한다.
|
||||
- 실시간 연결과 영속 저장을 분리해 생각한다.
|
||||
- MinIO는 첨부파일 저장소로는 괜찮지만 백업 저장소로 간주하지 않는다.
|
||||
- 운영 편의보다 복구 가능성을 우선한다.
|
||||
|
||||
## 2. 최종 권장 아키텍처 한 줄 요약
|
||||
|
||||
초기 최적안은 `단일 애플리케이션 계열 + PostgreSQL + Redis + MinIO + Caddy` 조합이다.
|
||||
|
||||
- 클라이언트 외부 프로토콜은 `HTTPS REST + WSS(WebSocket over TLS)`를 사용한다.
|
||||
- 서버 애플리케이션은 논리적으로 `API/Realtime/Worker`로 분리하되, 초기에는 같은 코드베이스와 같은 이미지에서 역할만 나눠 배포한다.
|
||||
- 영속 데이터는 PostgreSQL 하나를 기준축으로 삼는다.
|
||||
- Redis는 presence, 세션 인덱스, 단기 캐시, fan-out 보조 용도로만 사용하고, 진실의 원천으로 쓰지 않는다.
|
||||
- 첨부파일과 프로필 이미지는 MinIO에 저장하되 S3 호환 계층으로 추상화해서 이후 외부 오브젝트 스토리지로 쉽게 옮길 수 있게 한다.
|
||||
|
||||
## 3. 왜 이 아키텍처가 현재 VPS에 가장 적합한가
|
||||
|
||||
이 VPS는 단일 머신이다. 따라서 초기에 Kafka, 다수의 마이크로서비스, 복잡한 서비스 메시를 올리면 운영 부담이 가치보다 커진다. 반대로 단일 앱 컨테이너 하나에 모든 역할을 몰아넣고 Redis 없이 메모리만 사용하면, 나중에 멀티 인스턴스나 재시작 복구, presence 일관성, fan-out 제어에서 다시 뜯어고쳐야 한다.
|
||||
|
||||
따라서 가장 균형이 좋은 선택은 아래와 같다.
|
||||
|
||||
- 앱은 단순하게 유지한다.
|
||||
- 상태 저장은 PostgreSQL로 고정한다.
|
||||
- 연결 상태와 단기 이벤트 전달은 Redis에 맡긴다.
|
||||
- 첨부파일은 애플리케이션 로컬 디스크가 아니라 S3 호환 저장소로 보낸다.
|
||||
- 프록시는 Caddy로 단순화한다.
|
||||
|
||||
이렇게 하면 MVP에서는 운영 난이도가 낮고, 이후 앱 복제본을 늘릴 때도 방향이 유지된다.
|
||||
|
||||
## 4. 외부 프로토콜 권장안
|
||||
|
||||
### 4.1 클라이언트 통신
|
||||
|
||||
권장:
|
||||
|
||||
- 인증, 초기 동기화, 대화방 목록, 과거 메시지 조회, 첨부 업로드 시작/완료: `HTTPS REST`
|
||||
- 실시간 메시지 수신, 읽음 상태, 타이핑 상태, presence, 서버 이벤트 푸시: `WSS`
|
||||
|
||||
선택 이유:
|
||||
|
||||
- Windows 데스크톱에서 구현과 디버깅이 쉽다.
|
||||
- 프록시/Caddy/TLS 환경에서 안정적이다.
|
||||
- 모바일/웹 클라이언트로 확장해도 동일 패턴을 유지하기 쉽다.
|
||||
- gRPC streaming보다 도입 장벽이 낮고, 브라우저/데스크톱 지원이 직관적이다.
|
||||
|
||||
권장하지 않는 초기 선택:
|
||||
|
||||
- 순수 TCP 커스텀 프로토콜: 성능 이점보다 운영/보안/프록시 복잡성이 커진다.
|
||||
- MQTT: 메신저 도메인 모델과 인증/권한/히스토리 조회가 결국 별도 API를 필요로 하므로 단순해지지 않는다.
|
||||
- WebRTC data channel 중심 설계: P2P는 NAT, 오프라인 저장, 멀티 디바이스 동기화에 불리하다.
|
||||
|
||||
### 4.2 앱 레벨 메시지 프레임
|
||||
|
||||
초기부터 다음 개념은 반드시 포함한다.
|
||||
|
||||
- `message_id`: ULID 또는 UUIDv7
|
||||
- `conversation_id`
|
||||
- `sender_user_id`
|
||||
- `client_request_id`: 중복 전송 방지용
|
||||
- `server_sequence`: 대화방 단위 또는 사용자 inbox 단위 순서값
|
||||
- `sent_at`, `delivered_at`, `read_at`
|
||||
- `event_version`
|
||||
- `device_id`
|
||||
|
||||
이 필드가 있으면 이후 재전송, 읽음 동기화, 멀티 디바이스, 중복 ACK 처리, 서버 재시작 복구가 쉬워진다.
|
||||
|
||||
## 5. 서비스 구성 권장안
|
||||
|
||||
초기 컨테이너 구성:
|
||||
|
||||
- `messenger-caddy`
|
||||
외부 80/443 수신, TLS 종료, WebSocket 업그레이드 처리, 정적 헬스 라우팅
|
||||
- `messenger-app`
|
||||
REST API와 WebSocket 게이트웨이 역할 수행
|
||||
- `messenger-worker`
|
||||
outbox 처리, 알림 발행, 썸네일/미디어 후처리, 정리 배치 작업
|
||||
- `messenger-postgres`
|
||||
핵심 영속 데이터 저장소
|
||||
- `messenger-redis`
|
||||
presence, session map, short-lived cache, publish/subscribe 보조
|
||||
- `messenger-minio`
|
||||
첨부파일, 프로필 이미지, 미디어 저장
|
||||
- `messenger-backup`
|
||||
PostgreSQL 백업과 MinIO 메타/버킷 동기화 작업
|
||||
- `messenger-prometheus`
|
||||
메트릭 수집
|
||||
- `messenger-loki`
|
||||
로그 저장
|
||||
- `messenger-grafana`
|
||||
대시보드와 알림 뷰
|
||||
- `messenger-node-exporter` 또는 유사 호스트 메트릭 수집기
|
||||
VPS CPU, 메모리, 디스크, 네트워크 관측
|
||||
|
||||
중요한 점:
|
||||
|
||||
- `messenger-app`과 `messenger-worker`는 같은 코드베이스를 쓰는 것이 좋다.
|
||||
- 초기에는 마이크로서비스로 쪼개지 않는다.
|
||||
- 역할만 분리해 컨테이너를 나누면, 장애면을 분리하고 추후 스케일 아웃하기 쉬워진다.
|
||||
|
||||
## 6. 데이터 저장 전략
|
||||
|
||||
### 6.1 PostgreSQL을 중심으로 두는 이유
|
||||
|
||||
채팅 서비스는 결국 다음을 안정적으로 다뤄야 한다.
|
||||
|
||||
- 대화방 생성/멤버십
|
||||
- 메시지 영속화
|
||||
- 읽음 상태
|
||||
- 첨부 메타데이터
|
||||
- 차단/숨김/핀/알림 설정
|
||||
- 운영 감사 로그
|
||||
|
||||
이 영역은 관계형 정합성이 중요하다. PostgreSQL은 트랜잭션, 인덱스, JSONB, 전문 검색, WAL 기반 백업, 추후 복제까지 한 번에 가져갈 수 있다.
|
||||
|
||||
초기에는 NoSQL보다 PostgreSQL이 훨씬 안전하다.
|
||||
|
||||
### 6.2 핵심 테이블 범주
|
||||
|
||||
초기부터 분리해서 설계할 범주:
|
||||
|
||||
- 사용자/프로필
|
||||
- 디바이스/세션
|
||||
- 친구 관계 또는 연락처 매핑
|
||||
- 대화방
|
||||
- 대화방 멤버
|
||||
- 메시지
|
||||
- 메시지 첨부 메타
|
||||
- 메시지 전달 상태
|
||||
- 읽음 커서
|
||||
- 리액션
|
||||
- 차단/뮤트/보관
|
||||
- 감사 로그
|
||||
- 아웃박스 이벤트
|
||||
|
||||
핵심 원칙:
|
||||
|
||||
- 메시지 본문은 PostgreSQL에 저장한다.
|
||||
- 첨부파일 바이너리는 MinIO에 저장하고 DB에는 메타와 경로만 둔다.
|
||||
- 읽음 상태는 사용자별 커서 모델을 우선한다. 메시지별 읽음 row를 무분별하게 만들면 커진다.
|
||||
|
||||
### 6.3 Redis 역할 제한
|
||||
|
||||
Redis는 아래만 맡기는 것이 맞다.
|
||||
|
||||
- 온라인 사용자 presence TTL
|
||||
- 웹소켓 세션 라우팅 인덱스
|
||||
- 단기 rate limit 카운터
|
||||
- 최근 조회 캐시
|
||||
- 멀티 인스턴스 fan-out 보조 pub/sub
|
||||
|
||||
Redis를 진실의 원천으로 두면 복구와 디버깅이 어려워진다. 메시지 원본이나 유일한 unread 상태를 Redis에 넣는 것은 피한다.
|
||||
|
||||
## 7. 실시간 메시징 처리 흐름 권장안
|
||||
|
||||
메시지 전송 처리 흐름:
|
||||
|
||||
1. 클라이언트가 `client_request_id` 포함 메시지 전송
|
||||
2. 서버가 권한과 대화방 멤버십 확인
|
||||
3. PostgreSQL 트랜잭션에서 메시지 row 저장
|
||||
4. 같은 트랜잭션에서 outbox 이벤트 저장
|
||||
5. 커밋 성공 후 송신자에게 서버 확정 ACK 반환
|
||||
6. worker가 outbox를 읽고 수신자 online 세션으로 fan-out
|
||||
7. 수신 클라이언트 ACK 수신 후 전달 상태 갱신
|
||||
8. 읽음 이벤트는 별도 커서 업데이트로 처리
|
||||
|
||||
이 구조의 장점:
|
||||
|
||||
- DB 커밋 전송 실패와 푸시 실패를 분리할 수 있다.
|
||||
- 서버가 내려갔다가 올라와도 outbox 기준으로 재처리 가능하다.
|
||||
- 이후 Redis pub/sub에서 NATS JetStream 같은 것으로 바꿔도 모델이 유지된다.
|
||||
|
||||
## 8. 첨부파일/미디어 저장 전략
|
||||
|
||||
초기 권장:
|
||||
|
||||
- 원본 파일은 MinIO에 저장
|
||||
- 업로드는 서버에서 발급한 제한적 업로드 정책 또는 서버 경유 업로드 중 하나를 선택
|
||||
- MVP에서는 서버 경유 업로드가 구현은 쉽지만, 대용량에서 병목이 된다
|
||||
- 가능하면 초반부터 S3 호환 업로드 패턴으로 설계하는 것이 낫다
|
||||
|
||||
권장 메타데이터:
|
||||
|
||||
- object_key
|
||||
- original_filename
|
||||
- mime_type
|
||||
- byte_size
|
||||
- image_width, image_height
|
||||
- checksum
|
||||
- upload_status
|
||||
- virus_scan_status 또는 reserve 필드
|
||||
|
||||
확장 포인트:
|
||||
|
||||
- MinIO를 나중에 Cloudflare R2, AWS S3, Backblaze B2로 옮기기 쉽게 추상화
|
||||
- 썸네일과 프리뷰는 worker에서 비동기 생성
|
||||
|
||||
## 9. 인증/세션 전략
|
||||
|
||||
Windows PC만 먼저 개발하더라도 처음부터 아래를 고려한다.
|
||||
|
||||
- 사용자 계정과 디바이스 세션 분리
|
||||
- `device_id`를 가진 장치별 refresh session 유지
|
||||
- access token은 짧게, refresh token은 서버 추적 가능하게
|
||||
- 강제 로그아웃, 특정 디바이스 로그아웃, 세션 폐기 가능해야 함
|
||||
|
||||
권장:
|
||||
|
||||
- 앱 로그인 후 디바이스 세션 생성
|
||||
- WebSocket 연결 시 access token 검증
|
||||
- 세션 폐기 시 WebSocket 강제 끊기
|
||||
|
||||
이렇게 해야 추후 모바일 앱을 붙여도 모델을 바꾸지 않는다.
|
||||
|
||||
## 10. VPS 배포 전략
|
||||
|
||||
### 10.1 배포 방식
|
||||
|
||||
권장:
|
||||
|
||||
- Docker Compose 기반 단일 프로젝트 스택
|
||||
- systemd에서 compose 스택을 부팅 시 자동 기동
|
||||
- 상태 저장 볼륨은 명확히 분리
|
||||
|
||||
권장 볼륨 범주:
|
||||
|
||||
- PostgreSQL data
|
||||
- Redis data
|
||||
- MinIO data
|
||||
- Grafana data
|
||||
- Prometheus data
|
||||
- Loki data
|
||||
- 앱 업로드 임시 디렉터리
|
||||
|
||||
주의:
|
||||
|
||||
- 기존 VPS에 다른 서비스가 있다면 네트워크와 도메인을 분리해야 한다.
|
||||
- 외부 80/443을 이미 다른 Caddy가 쓰고 있다면, 새 메신저 스택은 기존 프록시에 역방향 프록시로 붙이는 방식이 가장 안전하다.
|
||||
- 메신저 전용 서브도메인을 분리한다. 예: `msg.example.com`, `api.msg.example.com`, `ws.msg.example.com`, `media.msg.example.com`
|
||||
|
||||
### 10.2 네트워크/포트
|
||||
|
||||
외부 공개는 최소화한다.
|
||||
|
||||
- 외부 공개: `80`, `443`, `22`
|
||||
- 내부 전용: PostgreSQL, Redis, MinIO 관리 포트, Grafana, Prometheus, Loki
|
||||
|
||||
원칙:
|
||||
|
||||
- DB/Redis/MinIO는 외부에 직접 열지 않는다.
|
||||
- 관리자 UI가 필요하면 VPN 또는 SSH 터널 기반 접근만 허용한다.
|
||||
|
||||
### 10.3 리소스 운영 방침
|
||||
|
||||
초기에는 다음 우선순위로 리소스를 배정한다.
|
||||
|
||||
1. PostgreSQL 메모리 보장
|
||||
2. 앱/WebSocket 연결 처리 여유 확보
|
||||
3. MinIO 디스크 여유 확보
|
||||
4. 관측성 스택은 과하지 않게 운영
|
||||
|
||||
관측 스택이 너무 무거우면 다음 순서로 경량화한다.
|
||||
|
||||
- Grafana 유지
|
||||
- Prometheus retention 축소
|
||||
- Loki retention 축소
|
||||
- 고해상도 scrape interval 완화
|
||||
|
||||
## 11. 관측성 설계
|
||||
|
||||
최소한 아래는 반드시 수집한다.
|
||||
|
||||
애플리케이션 메트릭:
|
||||
|
||||
- 활성 WebSocket 연결 수
|
||||
- 인증 성공/실패 수
|
||||
- 메시지 송신 TPS
|
||||
- 메시지 저장 지연
|
||||
- outbox 적체 수
|
||||
- fan-out 지연
|
||||
- 읽음 이벤트 처리량
|
||||
- 업로드 성공/실패 수
|
||||
- 대화방별 초당 메시지 폭주 탐지
|
||||
|
||||
인프라 메트릭:
|
||||
|
||||
- CPU
|
||||
- 메모리
|
||||
- 디스크 사용량
|
||||
- 디스크 IOPS
|
||||
- 네트워크 in/out
|
||||
- 컨테이너 재시작 횟수
|
||||
- PostgreSQL connections, replication lag 향후 대비
|
||||
- Redis memory eviction 여부
|
||||
|
||||
로그:
|
||||
|
||||
- JSON 구조화 로그
|
||||
- request_id, user_id, device_id, conversation_id, message_id 등 상관 키 포함
|
||||
- 인증 실패, 권한 오류, 메시지 저장 실패는 별도 레벨 관리
|
||||
|
||||
대시보드 우선순위:
|
||||
|
||||
1. 서비스 헬스
|
||||
2. 메시지 송수신 지연
|
||||
3. DB 상태
|
||||
4. 첨부 업로드 상태
|
||||
5. 에러 로그 상위 유형
|
||||
|
||||
## 12. 백업 및 복구 전략
|
||||
|
||||
가장 중요한 원칙:
|
||||
|
||||
- 같은 VPS 안의 다른 디렉터리에 저장한 사본은 백업이 아니다.
|
||||
- MinIO에 저장한 DB 덤프도 MinIO가 같은 머신에 있으면 재해 복구가 아니다.
|
||||
|
||||
권장 백업 구조:
|
||||
|
||||
- PostgreSQL: 일간 전체 백업 + 지속적 WAL 아카이빙
|
||||
- 백업 저장 위치: 외부 오브젝트 스토리지
|
||||
- MinIO 버킷 데이터: 주기적 외부 스토리지 동기화
|
||||
- 설정 파일과 compose 파일: Git 또는 암호화된 설정 저장소 별도 보관
|
||||
|
||||
복구 목표:
|
||||
|
||||
- RPO 목표: 5분에서 15분
|
||||
- RTO 목표: 1시간 이내
|
||||
|
||||
권장 운영 습관:
|
||||
|
||||
- 월 1회 복구 리허설
|
||||
- 최소 스테이징 환경으로 복원 테스트
|
||||
- 백업 성공 여부만 보지 말고 실제 복구 성공 여부 확인
|
||||
|
||||
## 13. 보안 권장안
|
||||
|
||||
초기 사이드 프로젝트라도 아래는 반드시 한다.
|
||||
|
||||
- root 비밀번호 SSH 로그인을 끄고 키 기반 인증으로 전환
|
||||
- fail2ban 또는 동등한 차단 장치 적용
|
||||
- firewalld/ufw로 외부 포트 최소화
|
||||
- Docker secrets 또는 최소한 권한 제한된 env 파일 사용
|
||||
- DB/Redis/MinIO 비밀번호 분리
|
||||
- TLS 강제
|
||||
- 관리자 계정 MFA 고려
|
||||
- 민감 로그 마스킹
|
||||
|
||||
애플리케이션 보안 체크포인트:
|
||||
|
||||
- rate limiting
|
||||
- 대화방 멤버십 권한 검사
|
||||
- 첨부파일 MIME 및 확장자 검증
|
||||
- 업로드 크기 제한
|
||||
- 악성 파일 검사 훅 준비
|
||||
- 세션 폐기와 토큰 로테이션
|
||||
|
||||
## 14. 스케일링 경로
|
||||
|
||||
### 단계 1. MVP
|
||||
|
||||
구성:
|
||||
|
||||
- 단일 VPS
|
||||
- 단일 `messenger-app`
|
||||
- 단일 `messenger-worker`
|
||||
- PostgreSQL 단일 인스턴스
|
||||
- Redis 단일 인스턴스
|
||||
- MinIO 단일 인스턴스
|
||||
|
||||
적합한 상황:
|
||||
|
||||
- 개인 프로젝트 초기
|
||||
- 소수 사용자
|
||||
- 운영자가 혼자일 때
|
||||
|
||||
### 단계 2. 같은 아키텍처로 성능 확장
|
||||
|
||||
구성 변화:
|
||||
|
||||
- 더 큰 VPS 또는 별도 앱 서버
|
||||
- `messenger-app` 복수 인스턴스
|
||||
- Redis 기반 세션 공유와 fan-out
|
||||
- PostgreSQL 튜닝 및 읽기 부하 분산 준비
|
||||
|
||||
필수 전제:
|
||||
|
||||
- WebSocket 세션 상태가 로컬 메모리에만 있지 않아야 함
|
||||
- outbox 기반 비동기 처리 구조가 이미 있어야 함
|
||||
|
||||
### 단계 3. 상태 저장 계층 분리
|
||||
|
||||
구성 변화:
|
||||
|
||||
- PostgreSQL을 관리형 또는 별도 전용 서버로 이동
|
||||
- MinIO를 외부 오브젝트 스토리지로 이동
|
||||
- Redis를 별도 인스턴스로 분리
|
||||
- 앱은 여러 대로 수평 확장
|
||||
|
||||
이 단계에서 바뀌면 좋은 것:
|
||||
|
||||
- 로드밸런서 도입
|
||||
- 무중단 배포
|
||||
- 관측성 경보 체계 정교화
|
||||
|
||||
### 단계 4. 더 큰 사용량
|
||||
|
||||
구성 변화:
|
||||
|
||||
- 내부 이벤트 버스를 Redis pub/sub에서 `NATS JetStream`으로 교체 또는 병행
|
||||
- PostgreSQL 읽기 복제본 도입
|
||||
- 검색을 외부 검색엔진으로 분리
|
||||
- 대화방 파티셔닝 또는 사용자 샤딩 검토
|
||||
|
||||
Kafka는 이 프로젝트 규모에서 너무 이른 선택일 가능성이 높다. NATS JetStream이 운영 난이도와 기능 균형이 더 좋다.
|
||||
|
||||
## 15. 마이그레이션 경로를 부드럽게 만드는 설계 포인트
|
||||
|
||||
초기부터 반드시 지켜야 하는 항목:
|
||||
|
||||
- 메시지 ID는 시간 정렬 가능한 전역 고유값 사용
|
||||
- DB 마이그레이션 체계 도입
|
||||
- 아웃박스 패턴 도입
|
||||
- 첨부 저장소는 S3 호환 인터페이스 뒤에 숨기기
|
||||
- 세션/프레즌스는 Redis 기반으로 외부화 가능하게 만들기
|
||||
- API 응답과 WebSocket 이벤트에 버전 필드 두기
|
||||
- 기능 플래그 도입
|
||||
|
||||
이것만 지켜도 단일 VPS에서 시작한 시스템을 크게 깨지 않고 다음 단계로 옮길 수 있다.
|
||||
|
||||
## 16. 자가 구현 서버 vs Matrix/기타 프로토콜 비교
|
||||
|
||||
### 16.1 이번 프로젝트의 권장 선택
|
||||
|
||||
이번 프로젝트는 `자가 구현 서버`가 더 적합하다.
|
||||
|
||||
이유:
|
||||
|
||||
- 카카오톡 PC 스타일 UX를 맞추려면 제품 흐름과 프로토콜을 세밀하게 제어해야 한다.
|
||||
- Matrix는 강력하지만 연합, 브리지, 규격 준수, 이벤트 모델 이해 비용이 크다.
|
||||
- 단일 VPS에서 개인 프로젝트로 운영하기에는 Synapse 계열은 무겁고 운영 난이도가 높다.
|
||||
- Element류 생태계와 맞물리는 장점보다, 제품 개성과 속도에서 제약이 더 크게 느껴질 가능성이 높다.
|
||||
|
||||
### 16.2 Matrix가 적합한 경우
|
||||
|
||||
- 오픈 프로토콜과 연합이 중요할 때
|
||||
- 외부 클라이언트 호환성이 중요할 때
|
||||
- 자체 프로토콜 설계보다 표준 기반 확장을 원할 때
|
||||
|
||||
### 16.3 기타 선택지
|
||||
|
||||
- XMPP: 성숙했지만 현대적인 제품 UX에 맞춘 구현에서는 다시 커스텀 계층이 많이 필요하다.
|
||||
- MQTT: IoT와 경량 pub/sub에는 좋지만 메신저 영속 모델과 권한 모델이 핵심이 아니므로 주축으로는 비권장이다.
|
||||
|
||||
결론:
|
||||
|
||||
- MVP와 제품 완성도 우선이라면 자가 구현
|
||||
- 개방형 생태계 우선이라면 Matrix
|
||||
|
||||
이번 케이스에서는 자가 구현이 맞다.
|
||||
|
||||
## 17. 실제 구축 순서 권장안
|
||||
|
||||
1. 도메인과 서브도메인 구조 확정
|
||||
2. Docker Compose 스택 초안 구성
|
||||
3. PostgreSQL 스키마와 마이그레이션 체계 확정
|
||||
4. 인증/세션 모델 확정
|
||||
5. REST + WSS 이벤트 계약서 작성
|
||||
6. outbox 기반 메시지 저장/전달 흐름 구현
|
||||
7. Redis presence 및 세션 인덱스 도입
|
||||
8. MinIO 첨부 업로드 흐름 도입
|
||||
9. Prometheus/Loki/Grafana 기본 대시보드 구성
|
||||
10. 외부 백업 파이프라인 연결
|
||||
11. 장애 복구 리허설
|
||||
12. 부하 테스트 후 튜닝
|
||||
|
||||
## 18. 최종 합의안
|
||||
|
||||
가장 현실적이고 좋은 방향은 아래다.
|
||||
|
||||
- 프로토콜은 `REST + WebSocket`
|
||||
- 서버 구조는 `모놀리식 코드베이스 + app/worker 역할 분리`
|
||||
- DB는 `PostgreSQL`
|
||||
- 캐시/프레즌스는 `Redis`
|
||||
- 첨부 저장소는 `MinIO(S3 호환)`
|
||||
- 프록시는 `Caddy`
|
||||
- 관측성은 `Prometheus + Loki + Grafana`
|
||||
- 백업은 `외부 오브젝트 스토리지로 분리`
|
||||
- 확장 경로는 `단일 VPS -> 앱 복제본 -> 상태 저장 계층 외부화 -> NATS/복제/샤딩`
|
||||
|
||||
이 구조는 사이드 프로젝트의 실행 가능성과, 이후 실제 사용자가 붙었을 때의 확장 가능성 사이에서 가장 균형이 좋다.
|
||||
Loading…
Add table
Add a link
Reference in a new issue