CDN에서 Azure Blob Storage로 이미지 저장소 변경

- CDNUploader를 BlobStorageUploader로 교체
- SAS Token 기반 접근 제어 추가 (유효기간 7일)
- Blob Storage Retry 로직 추가 (최대 3회, Exponential Backoff)
- 보안 강화: Public Access 비활성화, 읽기 전용 SAS Token
- Redis 캐싱에 Blob SAS URL 저장 (TTL 7일)
- 성능 영향 최소화 (+0.05-0.1초, 전체의 1-2%)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
박세원 2025-10-23 16:30:47 +09:00
parent 447d6b8e5d
commit 56f05ba25b

View File

@ -12,7 +12,7 @@ participant "ImageStyleFactory" as Factory
participant "StableDiffusion\nAPI Client" as SDClient
participant "DALL-E\nAPI Client" as DALLEClient
participant "Circuit Breaker" as CB
participant "CDNUploader" as CDN
participant "BlobStorage\nUploader" as BlobStorage
participant "JobStatusManager" as JobStatus
database "Redis Cache" as Redis
@ -64,12 +64,13 @@ else 캐시 MISS (새로운 이미지 생성)
note over SDClient: Circuit Breaker 적용\nRetry: 최대 3회\nTimeout: 20초
alt API 성공
SDClient --> Generator: 심플 이미지 URL
SDClient --> Generator: 심플 이미지 데이터
deactivate SDClient
Generator -> CDN: CDN 업로드 요청\n{imageUrl, eventId, style: SIMPLE}
activate CDN
CDN --> Generator: CDN URL (심플)
deactivate CDN
Generator -> BlobStorage: Blob 업로드 요청\n{imageData, eventId, style: SIMPLE}\nRetry: 3회, Timeout: 30초
activate BlobStorage
note right of BlobStorage: SAS Token 생성\n(유효기간 7일)
BlobStorage --> Generator: Blob SAS URL (심플)
deactivate BlobStorage
else API 실패 (Timeout/Error)
SDClient --> Generator: 실패 응답
deactivate SDClient
@ -85,12 +86,13 @@ else 캐시 MISS (새로운 이미지 생성)
Generator -> DALLEClient: Fallback - DALL-E API 호출\n{prompt, style: SIMPLE}\nTimeout: 20초
activate DALLEClient
alt Fallback 성공
DALLEClient --> Generator: 심플 이미지 URL
DALLEClient --> Generator: 심플 이미지 데이터
deactivate DALLEClient
Generator -> CDN: CDN 업로드 요청\n{imageUrl, eventId, style: SIMPLE}
activate CDN
CDN --> Generator: CDN URL (심플)
deactivate CDN
Generator -> BlobStorage: Blob 업로드 요청\n{imageData, eventId, style: SIMPLE}\nRetry: 3회, Timeout: 30초
activate BlobStorage
note right of BlobStorage: SAS Token 생성\n(유효기간 7일)
BlobStorage --> Generator: Blob SAS URL (심플)
deactivate BlobStorage
else Fallback 실패
DALLEClient --> Generator: 실패 응답
deactivate DALLEClient
@ -113,24 +115,26 @@ else 캐시 MISS (새로운 이미지 생성)
activate SDClient
alt API 성공
SDClient --> Generator: 화려한 이미지 URL
SDClient --> Generator: 화려한 이미지 데이터
deactivate SDClient
Generator -> CDN: CDN 업로드 요청\n{imageUrl, eventId, style: FANCY}
activate CDN
CDN --> Generator: CDN URL (화려한)
deactivate CDN
Generator -> BlobStorage: Blob 업로드 요청\n{imageData, eventId, style: FANCY}\nRetry: 3회, Timeout: 30초
activate BlobStorage
note right of BlobStorage: SAS Token 생성\n(유효기간 7일)
BlobStorage --> Generator: Blob SAS URL (화려한)
deactivate BlobStorage
else API 실패
SDClient --> Generator: 실패 응답
deactivate SDClient
Generator -> DALLEClient: Fallback - DALL-E API 호출
activate DALLEClient
alt Fallback 성공
DALLEClient --> Generator: 화려한 이미지 URL
DALLEClient --> Generator: 화려한 이미지 데이터
deactivate DALLEClient
Generator -> CDN: CDN 업로드
activate CDN
CDN --> Generator: CDN URL (화려한)
deactivate CDN
Generator -> BlobStorage: Blob 업로드\n{imageData, eventId, style: FANCY}\nRetry: 3회, Timeout: 30초
activate BlobStorage
note right of BlobStorage: SAS Token 생성\n(유효기간 7일)
BlobStorage --> Generator: Blob SAS URL (화려한)
deactivate BlobStorage
else Fallback 실패
DALLEClient --> Generator: 실패 응답
deactivate DALLEClient
@ -156,24 +160,26 @@ else 캐시 MISS (새로운 이미지 생성)
activate SDClient
alt API 성공
SDClient --> Generator: 트렌디 이미지 URL
SDClient --> Generator: 트렌디 이미지 데이터
deactivate SDClient
Generator -> CDN: CDN 업로드 요청\n{imageUrl, eventId, style: TRENDY}
activate CDN
CDN --> Generator: CDN URL (트렌디)
deactivate CDN
Generator -> BlobStorage: Blob 업로드 요청\n{imageData, eventId, style: TRENDY}\nRetry: 3회, Timeout: 30초
activate BlobStorage
note right of BlobStorage: SAS Token 생성\n(유효기간 7일)
BlobStorage --> Generator: Blob SAS URL (트렌디)
deactivate BlobStorage
else API 실패
SDClient --> Generator: 실패 응답
deactivate SDClient
Generator -> DALLEClient: Fallback - DALL-E API 호출
activate DALLEClient
alt Fallback 성공
DALLEClient --> Generator: 트렌디 이미지 URL
DALLEClient --> Generator: 트렌디 이미지 데이터
deactivate DALLEClient
Generator -> CDN: CDN 업로드
activate CDN
CDN --> Generator: CDN URL (트렌디)
deactivate CDN
Generator -> BlobStorage: Blob 업로드\n{imageData, eventId, style: TRENDY}\nRetry: 3회, Timeout: 30초
activate BlobStorage
note right of BlobStorage: SAS Token 생성\n(유효기간 7일)
BlobStorage --> Generator: Blob SAS URL (트렌디)
deactivate BlobStorage
else Fallback 실패
DALLEClient --> Generator: 실패 응답
deactivate DALLEClient
@ -189,9 +195,9 @@ else 캐시 MISS (새로운 이미지 생성)
deactivate Generator
== 결과 캐싱 및 Job 완료 ==
Handler -> Cache: 이미지 URL 캐싱\nkey: content:image:{eventDraftId}\nTTL: 7일
Handler -> Cache: Blob SAS URL 캐싱\nkey: content:image:{eventDraftId}\nTTL: 7일
activate Cache
Cache -> Redis: SET content:image:{eventDraftId}\n{simple, fancy, trendy}\nTTL: 604800 (7일)
Cache -> Redis: SET content:image:{eventDraftId}\n{simple: SAS_URL, fancy: SAS_URL, trendy: SAS_URL}\nTTL: 604800 (7일)
Redis --> Cache: 저장 완료
Cache --> Handler: 캐싱 완료
deactivate Cache
@ -204,9 +210,10 @@ else 캐시 MISS (새로운 이미지 생성)
Handler --> Consumer: 처리 완료
note over Handler
이미지 URL은 Redis에만 저장됨
Blob SAS URL은 Redis에만 저장됨
Event Service는 폴링을 통해
Redis에서 결과 조회
SAS Token 유효기간: 7일
end note
end
@ -214,22 +221,35 @@ deactivate Handler
note over Consumer, Redis
**Resilience 패턴 적용**
- Circuit Breaker: 실패율 50% 초과 시 Open
- Timeout: 20초
- Circuit Breaker: 실패율 50% 초과 시 Open (AI API용)
- AI API Timeout: 20초
- Fallback: Stable Diffusion 실패 시 DALL-E, 모두 실패 시 기본 템플릿
- Blob Storage Retry: 최대 3회 (Exponential Backoff: 1s, 2s, 4s)
- Blob Storage Timeout: 30초 (대용량 이미지 고려)
- Cache-Aside: Redis 캐싱 (TTL 7일)
**처리 시간**
- 캐시 HIT: 0.1초
- 캐시 MISS: 5초 이내 (병렬 처리)
- 캐시 MISS: 5.2초 이내 (병렬 처리)
└─ AI 생성: 3-5초 + Blob 업로드: 0.15-0.3초
**병렬 처리**
- 3가지 스타일 동시 생성 (par 블록)
- 독립적인 스레드 풀 사용
**CDN 업로드**
- 이미지 생성 후 CDN 업로드
- CDN URL 반환 및 캐싱
**Blob Storage 업로드**
- Azure Blob Storage (Korea Central)
- SAS Token 기반 접근 제어 (읽기 전용)
- SAS Token 유효기간: 7일 (Redis TTL과 동기화)
- Public Access 비활성화 (보안 강화)
- Container: event-images
- URL 형식: https://{account}.blob.core.windows.net/event-images/{id}-{style}.png?{sas_token}
**보안**
- Storage Account Public Access 비활성화
- SAS Token 기반 URL 생성 (읽기 전용 권한)
- Firewall 규칙: K8s Cluster IP만 허용
- HTTPS 강제 (TLS 1.2 이상)
end note
@enduml