Architecture

Architecture/System Design

[시스템 설계] 하루 한 번 알림을 “누락 없이” 보내기 위한 Redis 큐 & 워커 설계

1. 시스템 목표"하루에 한 번"과 같이 정해진 알림을 누락 없이 전송한다. (At-least-once Delivery)API 서버 장애, DB 장애, 애플리케이션 장애 등 어떤 상황에서도 작업 유실을 방지한다.장애 복구 시 발생할 수 있는 중복 발송을 최소화하고, 제어(멱등성)할 수 있도록 설계한다.2. 아키텍처 설계[1단계: 생산자 (Scheduler) 영역]별도의 스케줄러 스레드가 알림 발송 시간 10분 전에 User 테이블에서 알람 설정 한 유저 정보를 조회한다.유저 정보를 조회한 스케줄러는 오늘 알림 설정을 on 한 사용자들에 대해서만 quiz_notification_log 테이블을 생성하고 저장한다. (초기 status='PENDING')발송 시간이 되면 메인 스케줄러 스레드는 quiz_not..

Architecture/Domain Design

[ONCEO DDD 도메인 설계 시리즈 Part 6] 퀴즈 보기(QuizOption)는 왜 VO + JSON으로 설계했을까?

0. 들어가며 – “퀴즈 보기, 어디까지 쪼갤 건데?”내 서비스의 하루 학습 경험은 이렇게 생겼다.“키워드 설명을 읽고, 관련 뉴스를 보고, 마지막에 퀴즈 1문제를 푼다.그 퀴즈에는 여러 개의 보기(option) 가 달려 있다.”여기서 자연스럽게 나오는 질문이 있다.“이 보기(option) 를 DB에서 어디까지 테이블로 쪼갤까?”선택지는 크게 둘이었다.quiz_options 라는 테이블을 만들고,quiz_id 기준으로 1:N 로우를 두는 방식보기 전체를 하나의 값 객체(QuizOptions)로 보고,JSON 컬럼에 통째로 박아 넣는 방식나는 2번, 즉QuizOptions 값 객체내부에 ListJPA에서는 AttributeConverter + JSON TEXT 컬럼이 조합을 선택했다.이 글에서는왜 별도 테..

Architecture/Domain Design

[ONECO DDD 도메인 설계 시리즈 Part 4] 왜 DailyContent → News/Quiz(Entity)는 단방향으로만 묶었을까?

0. 이 글에서 이야기할 것oneco 콘텐츠의 도메인은 이렇게 생겼다.하루 단위 묶음: DailyContent (애그리거트 루트)그날 보여줄 뉴스들: NewsItem (엔티티 리스트)그날 풀게 될 퀴즈들: Quiz (엔티티 리스트)도메인 구조이번 글에서 이야기할 주제는 다음과 같다.“왜 DailyContent → News/Quiz 단방향만 만들고,NewsItem/Quiz → DailyContent 역방향은 안 만들었을까?”이 글에서는:지금 코드에서 DailyContent가 자식들을 어떻게 보호하고 검증하는지“만약 양방향으로 짰다면 코드가 어떻게 달라졌을지”JPA + DDD 관점에서 단방향 / 양방향 각각의 현실적인 장단점나중에 단방향이 막혀서 역방향이 필요해졌을 때 어떻게 확장할 계획인지까지, 실제 코드..

Architecture/Domain Design

[ONECO DDD 도메인 설계 시리즈 Part 3] 값 객체는 어디서 만들고, 엔티티는 누가 만들어야 할까?

이번 글은 ONECO 프로젝트에서 DailyContent 애그리거트를 설계하면서 부딪힌 고민들을 바탕으로,“값 객체(Value Object)는 어디서 만들고, 엔티티(Entity)는 누가 만들게 할 것인가?” 를 정리해보는 글이다.실제로 프로젝트를 진행하며 작성한 코드들로 정리해보았다.0. 개념 정리 : 엔티티 vs 값 객체엔티티(Entity)ID(정체성) 으로 구분된다.값이 조금 바뀌어도 “그 객체”로 계속 취급돼야 한다.애그리거트 루트 아래에 매달려 있는 내부 엔티티(예: OrderLine, Comment 등)도 포함.값 객체(Value Object)ID가 없다.값이 같으면 같은 것이다.가능하면 불변(immutable)에 가깝게 두고, 생성 시점에 유효성 검증을 끝낸다.“값 객체는 서비스에서 만들어도..

Architecture/Domain Design

[ONECO DDD 도메인 설계 시리즈 Part 2] DailyContent 애그리거트 뜯어보기

Part 1에서는 “왜 DailyContent를 애그리거트 루트로 두었는가”를 개념적으로 정리했다면,이번 Part 2는 실제 코드 한 파일(DailyContent.java)(애그리거트)을 기준으로 설계 의도와 동작 방식을 해부하는 글이다.0. 도메인 구조 & 전체 코드 원문먼저 기준이 되는 DailyContent 애그리거트 전체 코드이다.(프로젝트를 진행하며 수정되거나 추가될 수도 있다. 수정된 코드는 깃허브에서 확인할 수 있다.)@Entity@NoArgsConstructor(access = AccessLevel.PROTECTED)@Table(name = "daily_contents", uniqueConstraints = { @UniqueConstraint( name..

100points
'Architecture' 카테고리의 글 목록