mirror of
https://github.com/ktds-dg0501/kt-event-marketing.git
synced 2025-12-06 11:26:26 +00:00
논리 아키텍처 수정
주요 변경사항: - User Service 사업자번호 검증 로직 삭제 (국세청 API 제거) - User Service → Event Service 회원정보 제공 API 추가 - Redis 기반 서비스 간 데이터 공유 구조로 변경 - AI Service → Redis 저장 → Content Service 읽기 - Participation Service 참여자 목록 조회 기능 추가 - WinnerSelected 이벤트 토픽 제거 (3개 토픽으로 축소) - Redis → Event DB 저장 로직 추가 (이벤트 publish 시) - AI/Content Service Timeout 5분으로 변경 (30초/20초 → 300초) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
36e7e60ae3
commit
fb55fd85a0
@ -65,7 +65,7 @@
|
||||
1. **User Service**: 사용자 인증 및 매장정보 관리
|
||||
- 회원가입/로그인 (JWT 발급)
|
||||
- 프로필 CRUD
|
||||
- 사업자번호 검증 (국세청 API, Circuit Breaker)
|
||||
- Event Service로 회원정보 제공
|
||||
|
||||
2. **Event Service**: 이벤트 전체 생명주기 관리
|
||||
- 이벤트 생성/수정/삭제/조회
|
||||
@ -78,7 +78,7 @@
|
||||
- 참여 접수 및 중복 체크
|
||||
- 참여자 목록 조회
|
||||
- 당첨자 추첨 및 조회
|
||||
- Kafka Event 발행 (ParticipantRegistered, WinnerSelected)
|
||||
- Kafka Event 발행 (ParticipantRegistered)
|
||||
|
||||
4. **Analytics Service**: 실시간 성과 분석 및 대시보드
|
||||
- 대시보드 데이터 조회 (Redis 캐싱)
|
||||
@ -89,13 +89,13 @@
|
||||
#### Async Services (비동기 처리)
|
||||
1. **AI Service**: AI 기반 이벤트 추천
|
||||
- Kafka Job 구독 (ai 이벤트 생성)
|
||||
- 외부 AI API 호출 (Circuit Breaker, Timeout 30초)
|
||||
- 결과 캐싱 (Redis, TTL 24시간)
|
||||
- 외부 AI API 호출 (Circuit Breaker, Timeout 5분)
|
||||
- 결과 Redis 저장 (TTL 24시간)
|
||||
|
||||
2. **Content Service**: SNS 이미지 생성
|
||||
- Kafka Job 구독 (이미지 생성)
|
||||
- 외부 이미지 생성 API 호출 (Circuit Breaker, Timeout 20초)
|
||||
- CDN 업로드 및 캐싱 (Redis, TTL 7일)
|
||||
- Redis에서 AI 데이터 읽기
|
||||
- 외부 이미지 생성 API 호출 (Circuit Breaker, Timeout 5분)
|
||||
- 생성된 이미지 Redis 저장 (CDN URL, TTL 7일)
|
||||
|
||||
3. **Distribution Service**: 다중 채널 배포 (동기)
|
||||
- REST API 제공 (Event Service에서 호출)
|
||||
@ -106,7 +106,6 @@
|
||||
**Event Topics** (도메인 이벤트):
|
||||
- **EventCreated**: 이벤트 생성 시
|
||||
- **ParticipantRegistered**: 참여자 등록 시
|
||||
- **WinnerSelected**: 당첨자 선정 시
|
||||
- **DistributionCompleted**: 배포 완료 시
|
||||
|
||||
**Job Topics** (비동기 작업):
|
||||
@ -124,7 +123,6 @@
|
||||
- User DB, Event DB, Participation DB, Analytics DB
|
||||
|
||||
#### External Systems
|
||||
- **국세청 API**: 사업자번호 검증
|
||||
- **AI APIs**: Claude/GPT-4 (트렌드 분석)
|
||||
- **이미지 생성 APIs**: Stable Diffusion/DALL-E
|
||||
- **배포 채널 APIs**: 우리동네TV, 링고비즈, 지니TV, SNS APIs (비동기 배포)
|
||||
@ -139,20 +137,17 @@
|
||||
**핵심 책임**:
|
||||
- 회원가입/로그인 (JWT 토큰 발급)
|
||||
- 프로필 CRUD (매장 정보 포함)
|
||||
- 사업자번호 검증 (국세청 API 연동)
|
||||
- 세션 관리
|
||||
- Event Service로 회원정보 제공
|
||||
|
||||
**관련 유저스토리**: UFR-USER-010, 020, 030, 040
|
||||
|
||||
**Resilience 패턴**:
|
||||
- **Circuit Breaker**: 국세청 API 호출 시 (실패율 50% 초과 시 Open)
|
||||
- **Retry**: 최대 3회 재시도 (지수 백오프: 1초, 2초, 4초)
|
||||
- **Timeout**: 5초
|
||||
- **Fallback**: 사업자번호 검증 스킵 (수동 확인 안내)
|
||||
**서비스 간 호출**:
|
||||
- **Event Service**: 회원정보 조회 API 제공 (매장 정보 포함)
|
||||
|
||||
**데이터 저장**:
|
||||
- User DB: users, stores 테이블
|
||||
- Redis: 세션 정보 (TTL 7일), 사업자번호 검증 결과 (TTL 7일)
|
||||
- Redis: 세션 정보 (TTL 7일)
|
||||
|
||||
#### Event Service
|
||||
**핵심 책임**:
|
||||
@ -189,7 +184,7 @@
|
||||
- 이벤트 참여 접수 및 검증
|
||||
- 참여자 목록 조회
|
||||
- 당첨자 추첨 및 조회
|
||||
- Kafka Event 발행 (ParticipantRegistered, WinnerSelected)
|
||||
- Kafka Event 발행 (ParticipantRegistered)
|
||||
|
||||
**관련 유저스토리**: UFR-PART-010, 020, 030
|
||||
|
||||
@ -198,14 +193,12 @@
|
||||
- Payload: participantId, eventId, phoneNumber, registeredAt
|
||||
- 구독자: Analytics Service
|
||||
|
||||
2. **WinnerSelected**: 당첨자 선정 시
|
||||
- Payload: winnerId, eventId, selectedAt
|
||||
- 구독자: (추후 확장 가능)
|
||||
|
||||
**주요 기능**:
|
||||
- 중복 참여 체크 (전화번호 기반)
|
||||
- 참여자 목록 조회 (페이지네이션 지원)
|
||||
- 난수 기반 무작위 추첨
|
||||
- 매장 방문 고객 가산점 적용
|
||||
- 당첨자 조회
|
||||
|
||||
**데이터 저장**:
|
||||
- Participation DB: participants, winners 테이블
|
||||
@ -252,13 +245,13 @@
|
||||
|
||||
**Resilience 패턴**:
|
||||
- **Circuit Breaker**: AI API 호출 시 (실패율 50% 초과 시 Open)
|
||||
- **Timeout**: 30초
|
||||
- **Timeout**: 5분 (300초)
|
||||
- **Fallback**: 캐시된 이전 추천 결과 + 안내 메시지
|
||||
- **Cache-Aside**: Redis 캐싱 (TTL 24시간)
|
||||
|
||||
**처리 시간**:
|
||||
- 캐시 HIT: 0.1초
|
||||
- 캐시 MISS: 10초 이내 (비동기 처리)
|
||||
- 캐시 MISS: 5분 이내 (비동기 처리)
|
||||
|
||||
**데이터 저장**:
|
||||
- Redis: AI 추천 결과 (TTL 24시간)
|
||||
@ -272,18 +265,18 @@
|
||||
|
||||
**관련 유저스토리**: UFR-CONT-010, 020
|
||||
|
||||
**Kafka Job 구독**:
|
||||
- **이미지 생성**: 이미지 생성 작업 요청
|
||||
**데이터 읽기**:
|
||||
- Redis에서 AI Service가 저장한 이벤트 데이터 읽기
|
||||
|
||||
**Resilience 패턴**:
|
||||
- **Circuit Breaker**: 이미지 생성 API 호출 시 (실패율 50% 초과 시 Open)
|
||||
- **Timeout**: 20초
|
||||
- **Timeout**: 5분 (300초)
|
||||
- **Fallback**: 기본 템플릿 이미지 제공
|
||||
- **Cache-Aside**: Redis 캐싱 (TTL 7일)
|
||||
|
||||
**처리 시간**:
|
||||
- 캐시 HIT: 0.1초
|
||||
- 캐시 MISS: 5초 이내 (비동기 처리)
|
||||
- 캐시 MISS: 5분 이내 (비동기 처리)
|
||||
|
||||
**데이터 저장**:
|
||||
- Redis: 이미지 생성 결과 (CDN URL, TTL 7일)
|
||||
@ -335,7 +328,6 @@
|
||||
|---------|--------|--------|---------|------|
|
||||
| **EventCreated** | Event Service | Analytics Service | eventId, storeId, title, objective, createdAt | 이벤트 생성 시 통계 초기화 |
|
||||
| **ParticipantRegistered** | Participation Service | Analytics Service | participantId, eventId, phoneNumber, registeredAt | 참여자 등록 시 실시간 통계 업데이트 |
|
||||
| **WinnerSelected** | Participation Service | - | winnerId, eventId, selectedAt | 당첨자 선정 기록 |
|
||||
| **DistributionCompleted** | Distribution Service | Analytics Service | eventId, distributedChannels, completedAt | 배포 완료 시 통계 업데이트 |
|
||||
|
||||
#### Job Topics (비동기 작업)
|
||||
@ -429,9 +421,8 @@
|
||||
- **설정**:
|
||||
| 서비스 | Timeout | 이유 |
|
||||
|--------|---------|------|
|
||||
| User Service (국세청 API) | 5초 | 빠른 검증 필요 |
|
||||
| AI Service (AI API) | 30초 | 복잡한 분석 작업 |
|
||||
| Content Service (이미지 API) | 20초 | 이미지 생성 시간 고려 |
|
||||
| AI Service (AI API) | 5분 (300초) | 복잡한 분석 작업 |
|
||||
| Content Service (이미지 API) | 5분 (300초) | 이미지 생성 시간 고려 |
|
||||
| Distribution Service (채널 APIs) | 10초 | 빠른 배포 필요 |
|
||||
|
||||
**4. Bulkhead 패턴**
|
||||
@ -449,7 +440,6 @@
|
||||
- **전략**:
|
||||
| 서비스 | Fallback 전략 |
|
||||
|--------|---------------|
|
||||
| User Service | 사업자번호 검증 스킵 (수동 확인 안내) |
|
||||
| AI Service | 캐시된 이전 추천 결과 + 안내 메시지 |
|
||||
| Content Service | 기본 템플릿 이미지 제공 |
|
||||
| Distribution Service | 실패 채널 스킵 + 알림 |
|
||||
@ -497,8 +487,8 @@
|
||||
│ AI Service (Background) │
|
||||
│ - Kafka ai 이벤트 생성 토픽 구독 │
|
||||
│ - Redis 캐시 확인 (Cache-Aside) │
|
||||
│ - 캐시 MISS: Claude API 호출 (10초) [Circuit Breaker] │
|
||||
│ - 결과 캐싱 (TTL 24시간) │
|
||||
│ - 캐시 MISS: Claude API 호출 (5분) [Circuit Breaker] │
|
||||
│ - AI 추천 결과를 Redis에 저장 (TTL 24시간) │
|
||||
│ - Job 상태 완료로 업데이트 │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
|
||||
@ -509,20 +499,13 @@
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
|
||||
3. [SNS 이미지 생성]
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Client → Event Service │
|
||||
│ - POST /api/events/{id}/content-generation │
|
||||
│ - Kafka 이미지 생성 토픽 발행 (이미지 생성 요청) │
|
||||
│ - Job ID 즉시 반환 (0.1초) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Content Service (Background) │
|
||||
│ - Kafka 이미지 생성 토픽 구독 │
|
||||
│ - Redis 캐시 확인 │
|
||||
│ - 캐시 MISS: Stable Diffusion API (5초) [Circuit Breaker] │
|
||||
│ - Redis에서 AI Service가 저장한 이벤트 데이터 읽기 │
|
||||
│ - Redis 캐시 확인 (이미지 생성 여부) │
|
||||
│ - 캐시 MISS: Stable Diffusion API (5분) [Circuit Breaker] │
|
||||
│ - 이미지 CDN 업로드 │
|
||||
│ - CDN URL 캐싱 (TTL 7일) │
|
||||
│ - 생성된 이미지 URL을 Redis에 저장 (TTL 7일) │
|
||||
│ - Job 상태 완료로 업데이트 │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
|
||||
@ -536,6 +519,8 @@
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Client → Event Service │
|
||||
│ - POST /api/events/{id}/publish │
|
||||
│ - Redis의 이벤트 관련 정보(AI 추천, 이미지 URL)를 조회 │
|
||||
│ - Event DB에 이벤트 정보 저장 │
|
||||
│ - Event 상태 변경 (DRAFT → PUBLISHED) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
|
||||
@ -591,7 +576,6 @@
|
||||
│ - POST /api/events/{id}/draw-winners │
|
||||
│ - 난수 기반 무작위 추첨 │
|
||||
│ - Winners DB에 저장 │
|
||||
│ - WinnerSelected 이벤트 발행 → Kafka │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
@ -679,8 +663,8 @@
|
||||
| 서비스 | 캐시 키 패턴 | 데이터 타입 | TTL | 예상 크기 | 히트율 목표 |
|
||||
|--------|-------------|-----------|-----|----------|-----------|
|
||||
| User | `user:session:{token}` | String | 7일 | 1KB | - |
|
||||
| User | `user:business:{사업자번호}` | String | 7일 | 0.5KB | 90% |
|
||||
| AI | `ai:recommendation:{업종}:{지역}:{목적}` | Hash | 24시간 | 10KB | 80% |
|
||||
| AI | `ai:event:{이벤트ID}` | Hash | 24시간 | 10KB | - |
|
||||
| Content | `content:image:{이벤트ID}:{스타일}` | String | 7일 | 0.2KB (URL) | 80% |
|
||||
| Analytics | `analytics:dashboard:{이벤트ID}` | Hash | 5분 | 5KB | 95% |
|
||||
| AI | `job:{jobId}` | Hash | 1시간 | 1KB | - |
|
||||
@ -857,13 +841,16 @@
|
||||
### B. 주요 결정사항
|
||||
1. **Kafka 통합 메시징 플랫폼 채택**: Event Bus와 Job Queue를 Kafka로 통합하여 운영 복잡도 감소
|
||||
2. **Event-Driven 아키텍처 채택**: Kafka를 통한 서비스 간 느슨한 결합 및 비동기 통신
|
||||
3. **도메인 이벤트 정의**: 4개 Event Topics (EventCreated, ParticipantRegistered, WinnerSelected, DistributionCompleted)
|
||||
3. **도메인 이벤트 정의**: 3개 Event Topics (EventCreated, ParticipantRegistered, DistributionCompleted)
|
||||
4. **Job Topics 정의**: 2개 Job Topics (ai 이벤트 생성, 이미지 생성)로 장시간 비동기 작업 처리
|
||||
5. **Resilience 패턴 전면 적용**: Circuit Breaker, Retry, Timeout, Bulkhead, Fallback
|
||||
6. **At-Least-Once Delivery**: Kafka 메시지 보장 및 멱등성 설계
|
||||
7. **Cache-Aside 패턴**: AI/이미지 생성 결과 캐싱으로 응답 시간 90% 개선
|
||||
8. **동기 배포**: Event Service가 Distribution Service를 REST API로 직접 호출하여 다중 채널 배포 동기 처리
|
||||
9. **서비스별 독립 Database**: Database-per-Service 패턴으로 서비스 독립성 보장
|
||||
8. **Redis 기반 서비스 간 데이터 공유**: AI Service → Redis → Content Service 데이터 흐름
|
||||
9. **Redis to DB 영구 저장**: 이벤트 생성 완료 시 Redis 데이터를 Event DB에 저장
|
||||
10. **동기 배포**: Event Service가 Distribution Service를 REST API로 직접 호출하여 다중 채널 배포 동기 처리
|
||||
11. **서비스별 독립 Database**: Database-per-Service 패턴으로 서비스 독립성 보장
|
||||
12. **장시간 작업 Timeout 조정**: AI/Content Service Timeout을 5분으로 설정하여 복잡한 생성 작업 지원
|
||||
|
||||
### C. 향후 개선 방안 (Phase 2 이후)
|
||||
1. **Event Sourcing 완전 적용**: 모든 상태 변경을 이벤트로 저장하여 시간 여행 및 감사 추적 강화
|
||||
|
||||
@ -3,34 +3,35 @@ graph TB
|
||||
|
||||
%% Services
|
||||
subgraph "Services"
|
||||
UserSvc["User Service<br/>• 회원가입/로그인<br/>• 프로필 관리<br/>• 사업자번호 검증<br/>[Circuit Breaker]"]
|
||||
EventSvc["Event Service<br/>• 이벤트 생성/수정/삭제<br/>• 플로우 오케스트레이션<br/>• AI/이미지 작업 요청<br/>• 배포 작업 요청"]
|
||||
PartSvc["Participation<br/>Service<br/>• 참여 접수<br/>• 당첨자 추첨"]
|
||||
UserSvc["User Service<br/>• 회원가입/로그인<br/>• 프로필 관리<br/>• 회원정보 제공"]
|
||||
EventSvc["Event Service<br/>• 이벤트 생성/수정/삭제<br/>• 플로우 오케스트레이션<br/>• AI 작업 요청<br/>• 배포 작업 요청<br/>• Redis → DB 저장"]
|
||||
PartSvc["Participation<br/>Service<br/>• 참여 접수<br/>• 참여자 목록<br/>• 당첨자 추첨"]
|
||||
AnalSvc["Analytics Service<br/>• 실시간 대시보드<br/>• 성과 분석<br/>• 채널별 통계<br/>[Circuit Breaker]"]
|
||||
end
|
||||
|
||||
%% Async Services
|
||||
subgraph "Async Services"
|
||||
AISvc["AI Service<br/>• 트렌드 분석<br/>• 이벤트 추천<br/>[Circuit Breaker]<br/>[Timeout: 30s]"]
|
||||
ContentSvc["Content Service<br/>• SNS 이미지 생성<br/>• 3가지 스타일<br/>[Circuit Breaker]<br/>[Timeout: 20s]"]
|
||||
AISvc["AI Service<br/>• 트렌드 분석<br/>• 이벤트 추천<br/>• Redis 저장<br/>[Circuit Breaker]<br/>[Timeout: 5분]"]
|
||||
ContentSvc["Content Service<br/>• Redis 데이터 읽기<br/>• SNS 이미지 생성<br/>• Redis 저장<br/>[Circuit Breaker]<br/>[Timeout: 5분]"]
|
||||
DistSvc["Distribution<br/>Service<br/>• 다중 채널 배포<br/>[Circuit Breaker]<br/>[Retry: 3회]<br/>[Bulkhead]"]
|
||||
end
|
||||
|
||||
%% Kafka (Event Bus + Job Queue)
|
||||
Kafka["Kafka<br/>━━━━━━━━━━<br/><Event Topics><br/>• EventCreated<br/>• ParticipantRegistered<br/>• WinnerSelected<br/>• DistributionCompleted<br/>━━━━━━━━━━<br/><Job Topics><br/>• ai 이벤트 생성<br/>• 이미지 생성"]
|
||||
Kafka["Kafka<br/>━━━━━━━━━━<br/><Event Topics><br/>• EventCreated<br/>• ParticipantRegistered<br/>• DistributionCompleted<br/>━━━━━━━━━━<br/><Job Topics><br/>• ai 이벤트 생성"]
|
||||
|
||||
%% External System
|
||||
External["외부시스템<br/>[Circuit Breaker]<br/>━━━━━━━━━━<br/>• 국세청 API<br/>• AI API<br/>• 이미지 생성 API<br/>• 배포 채널 APIs<br/>(비동기)"]
|
||||
External["외부시스템<br/>[Circuit Breaker]<br/>━━━━━━━━━━<br/>• AI API<br/>• 이미지 생성 API<br/>• 배포 채널 APIs<br/>(비동기)"]
|
||||
|
||||
%% Redis
|
||||
Redis["Redis Cache<br/>━━━━━━━━━━<br/>• AI 결과<br/>• 이미지 URL<br/>• 이벤트 데이터"]
|
||||
|
||||
%% Event Publishing
|
||||
EventSvc ==>|"EventCreated<br/>발행"| Kafka
|
||||
PartSvc ==>|"ParticipantRegistered<br/>발행"| Kafka
|
||||
PartSvc ==>|"WinnerSelected<br/>발행"| Kafka
|
||||
DistSvc ==>|"DistributionCompleted<br/>발행"| Kafka
|
||||
|
||||
%% Job Publishing (비동기 작업 요청)
|
||||
EventSvc -->|"ai 이벤트 생성 발행"| Kafka
|
||||
EventSvc -->|"이미지 생성 발행"| Kafka
|
||||
|
||||
%% Event Subscription
|
||||
Kafka -.->|"EventCreated<br/>구독"| AnalSvc
|
||||
@ -39,13 +40,18 @@ graph TB
|
||||
|
||||
%% Job Subscription
|
||||
Kafka -.->|"ai 이벤트 생성 구독"| AISvc
|
||||
Kafka -.->|"이미지 생성 구독"| ContentSvc
|
||||
|
||||
%% Service to Service (동기 호출)
|
||||
EventSvc -->|"다중 채널 배포<br/>[Circuit Breaker]"| DistSvc
|
||||
EventSvc -->|"회원정보 조회"| UserSvc
|
||||
|
||||
%% Redis Interactions
|
||||
AISvc -->|"AI 결과 저장"| Redis
|
||||
ContentSvc -->|"AI 데이터 읽기"| Redis
|
||||
ContentSvc -->|"이미지 URL 저장"| Redis
|
||||
EventSvc -->|"Redis → DB 저장"| Redis
|
||||
|
||||
%% Services to External (Resilience 패턴)
|
||||
UserSvc -->|"사업자번호 검증<br/>[Retry: 3회]"| External
|
||||
AISvc -->|"트렌드 분석/추천"| External
|
||||
ContentSvc -->|"이미지 생성"| External
|
||||
DistSvc -->|"다중 채널 배포<br/>(비동기)"| External
|
||||
@ -56,8 +62,10 @@ graph TB
|
||||
classDef async fill:#8B5CF6,stroke:#7C3AED,stroke-width:3px,color:#fff
|
||||
classDef kafka fill:#F59E0B,stroke:#D97706,stroke-width:3px
|
||||
classDef external fill:#E5E7EB,stroke:#9CA3AF,stroke-width:2px
|
||||
classDef cache fill:#EF4444,stroke:#DC2626,stroke-width:3px
|
||||
|
||||
class UserSvc,EventSvc,PartSvc,AnalSvc service
|
||||
class AISvc,ContentSvc,DistSvc async
|
||||
class Kafka kafka
|
||||
class External external
|
||||
class Redis cache
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user