- λΉμ¦λμ€ λ‘μ§ μ€ λ°μ κ°λ₯ν λμμ± μ΄μ νμ
- λκΈ°μ΄ Redis μ΄κ΄ λ° Cache Service λμ
- λΆνλ₯Ό μ μ νκ² μΆμνκΈ° μν λ°©μ κ³ λ €
- MSA μλΉμ€ λΆλ¦¬ νμ₯ μ€κ³
- λΆν ν μ€νΈ
- λκΈ°μ΄ μμ€ν μ ν΅ν΄ μ μ νΈλν½μ κ΄λ¦¬ν μ μλ€.
- μμ½ μλΉμ€λ ν ν°μ΄ μλ μ μ λ§ μνν μ μλ€.
- μ’μ μμ½ μμ² μ, κ²°μ κ° μ΄λ£¨μ΄μ§μ§ μλλΌλ μΌμ μκ°λμ λ€λ₯Έ μ μ κ° ν΄λΉ μ’μμ μ κ·Όν μ μλλ‘ νλ€.
- κ²°μ μ, μ¬μ©μλ 미리 μΆ©μ ν μμ‘μ μ΄μ©νλ€.
- λκΈ°μ΄ ν ν° λ±λ‘ λ° μ‘°ν API
- μ½μνΈ λͺ©λ‘ μ‘°ν API
- μ½μνΈ μΌμ λͺ©λ‘ μ‘°ν API
- μ½μνΈ μ’μ λͺ©λ‘ μ‘°ν API
- μ½μνΈ μμ½ μμ² API
- μ½μνΈ μ’μ κ²°μ API
1οΈβ£ μ μ λκΈ°μ΄ ν ν° κΈ°λ₯
- μλΉμ€λ₯Ό μ΄μ©ν ν ν°μ λ°κΈλ°λ API λ₯Ό μμ±νλ€.
- ν ν°μ μ μ μ UUID μ ν΄λΉ μ μ μ λκΈ°μ΄μ κ΄λ¦¬ν μ μλ μ 보 ( λκΈ° μμ or μμ¬ μκ° λ± ) λ₯Ό ν¬ν¨νλ€.
- μ΄ν λͺ¨λ API λ μ ν ν°μ μ΄μ©ν΄ λκΈ°μ΄ κ²μ¦μ ν΅κ³Όν΄μΌ μ΄μ© κ°λ₯νλ€.
κΈ°λ³Έμ μΌλ‘ ν΄λ§μΌλ‘ λ³ΈμΈμ λκΈ°μ΄μ νμΈνλ€κ³ κ°μ νλ€.
2οΈβ£ μ½μνΈ λ μ§ / μ’μ API
- μ½μνΈ λ μ§μ ν΄λΉ λ μ§μ μ’μμ μ‘°ννλ API λ₯Ό κ°κ° μμ±νλ€.
- μ½μνΈ λ μ§ λͺ©λ‘μ μ‘°νν μ μλ€.
- λ μ§ μ 보λ₯Ό μ λ ₯λ°μ μμ½ κ°λ₯ν μ’μ μ 보λ₯Ό μ‘°νν μ μλ€.
μ’μ μ 보λ 1 ~ 50 κΉμ§μ μ’μ λ²νΈλ‘ κ΄λ¦¬λλ€.
3οΈβ£ μ½μνΈ μ’μ μμ½ μμ² API
- λ μ§μ μ’μ μ 보λ₯Ό μ λ ₯ λ°μ μ’μμ μμ½ μ²λ¦¬νλ API λ₯Ό μμ±νλ€.
- μ’μ μμ½κ³Ό λμμ ν΄λΉ μ’μμ κ·Έ μ μ μκ² μ½ 5λΆκ° μμ λ°°μ λλ€.
- λ§μ½ λ°°μ μκ° λ΄μ κ²°μ κ° μλ£λμ§ μλλ€λ©΄, μ’μμ λν μμ λ°°μ μ ν΄μ λμ΄μΌ νλ©° λ€λ₯Έ μ¬μ©μλ μμ½ν μ μμ΄μΌ νλ€.
4οΈβ£ μ μ μμ‘ μΆ©μ / μ‘°ν API
- κ²°μ μ μ¬μ©λ κΈμ‘μ API λ₯Ό ν΅ν΄ μΆ©μ νλ API λ₯Ό μμ±νλ€.
- μ¬μ©μ μλ³μ λ° μΆ©μ ν κΈμ‘μ λ°μ μμ‘μ μΆ©μ νλ€.
- μ¬μ©μ μλ³μλ₯Ό ν΅ν΄ ν΄λΉ μ¬μ©μμ μμ‘μ μ‘°ννλ€.
5οΈβ£ κ²°μ API
- κ²°μ μ²λ¦¬νκ³ κ²°μ λ΄μμ μμ±νλ API λ₯Ό μμ±νλ€.
- κ²°μ κ° μλ£λλ©΄ ν΄λΉ μ’μμ μμ κΆμ μ μ μκ² λ°°μ νκ³ λκΈ°μ΄ ν ν°μ λ§λ£μν¨λ€.
π‘ KEY POINT
- μ μ κ° λκΈ°μ΄ μμ²μ μμλλ‘ μ ννκ² μ΄λ»κ² μ 곡ν κ²μΈκ°?
- λμμ μ¬λ¬ μ¬μ©μκ° μμ½ μμ²μ νμ λ, μ’μμ΄ μ€λ³΅μΌλ‘ λ°°μ κ°λ₯νμ§ μλλ‘ ν΄μΌ νλ€.
https://github.com/users/kdelay/projects/7/views/4
erDiagram
%% μ¬μ©μ
user {
bigint id PK "μ μ PK"
decimal amount "μμ‘"
}
%% λκΈ°μ΄ ν ν° μ 보
%% user(1) : waiting_slot(N)
waiting_token {
bigint id PK "λκΈ°μ΄ PK"
bigint user_id FK "μ μ PK"
string token UK "ν ν° μ 보(UUID)"
%% DEACTIVATE(λΉνμ±ν), ACTIVATE(νμ±ν), EXPIRED(λ§λ£λ¨)
string waiting_token_status "λκΈ°μ΄ ν ν° μν(enum)"
timestamp created_at "λκΈ°μ΄ ν ν° μμ² μκ°"
timestamp modified_at "λκΈ°μ΄ ν ν° μν λ³κ²½ μκ°"
}
%% μ½μνΈ
concert {
bigint id PK "μ½μνΈ PK"
string name "μ½μνΈ μ΄λ¦"
string host "μ½μνΈ μ£Όμ΅μ"
}
%% μ½μνΈ λ μ§
%% concert(1) : concert_schedule(N)
concert_schedule {
bigint id PK "μ½μνΈ λ μ§ PK"
bigint concert_id FK "μ½μνΈ PK"
date concert_date "μ½μνΈ λ μ§"
}
%% μ½μνΈ μ’μ
%% concert_schedule(1) : concert_seat(N)
concert_seat {
bigint id PK "μ½μνΈ μ’μ PK"
bigint concert_id FK "μ½μνΈ PK"
bigint concert_schedule_id FK "μ½μνΈ λ μ§ PK"
bigint user_id FK "μ μ PK"
int seat_number "μ½μνΈ μ’μ λ²νΈ"
decimal seat_price "μ½μνΈ μ’μ κΈμ‘"
%% AVAILABLE(μμ½ κ°λ₯), TEMPORARY(μμ μ’μ λ°°μ μ€), RESERVED(μμ½λ¨)
string seat_status "μ½μνΈ μ’μ λ²νΈ μν(enum)"
timestamp modified_at "μ½μνΈ μ’μ μν λ³κ²½ μκ°"
timestamp expired_at "μμ λ°°μ λ§λ£ μκ°"
}
%% μμ½
%% user(1) : reservation(N)
reservation {
bigint id PK "μ½μνΈ μμ½ PK"
bigint concert_seat_id FK "μ½μνΈ μ’μ PK"
bigint user_id FK "μ μ PK"
string concert_name "μ½μνΈ μ΄λ¦"
date concert_date "μ½μνΈ λ μ§"
%% RESERVING(μμ½μ€), RESERVED(μμ½λ¨), CANCELED(μμ½ μ·¨μ)
string reservation_status "μμ½ μν(enum)"
timestamp created_at "μ½μνΈ μμ½ μμ² μκ°"
timestamp modified_at "μ½μνΈ μμ½ μν λ³κ²½ μκ°"
}
%% κ²°μ
%% reservation(1) : payment(0 or 1)
payment {
bigint id PK "μ½μνΈ κ²°μ PK"
bigint reservation_id FK "μ½μνΈ μμ½ PK"
decimal price "κ²°μ κΈμ‘"
%% COMPLETED(κ²°μ μλ£), CANCELED(κ²°μ μ·¨μ)
string payment_state "κ²°μ μν(enum)"
timestamp created_at "μ½μνΈ κ²°μ μμ² μκ°"
timestamp modified_at "μ½μνΈ κ²°μ μν λ³κ²½ μκ°"
}
user ||--|{ waiting_token : has
concert ||--|{ concert_schedule : contains
concert_schedule ||--|{ concert_seat : contains
reservation ||--o| payment : has
sequenceDiagram
autonumber
actor μ¬μ©μ
μ¬μ©μ ->>+ λκΈ°μ΄: ν ν° μμ²
Note over μ¬μ©μ, λκΈ°μ΄: μ¬μ©μ μλ³μ(pk)
λκΈ°μ΄ ->> λκΈ°μ΄: λκΈ°μ€μΈ ν ν°μ΄ μλ κ²½μ° μλ‘ λ°κΈ, μλ κ²½μ° λ°ν
λκΈ°μ΄ -->>- μ¬μ©μ: ν ν°, λκΈ°μ΄ μ 보
sequenceDiagram
autonumber
actor μ¬μ©μ
μ¬μ©μ ->>+ λκΈ°μ΄: λκΈ°μ΄ μμ²
break λκΈ°μ΄ κ²μ¦ μ€ν¨
λκΈ°μ΄ -->> μ¬μ©μ: 400 Error λ°ν
end
μ¬μ©μ ->>+ μμ½ κ°λ₯ λ μ§: μ½μνΈ λ μ§ μ‘°ν μμ²
Note over μ¬μ©μ, μμ½ κ°λ₯ λ μ§: Active ν ν°, μ½μνΈ μ 보
μμ½ κ°λ₯ λ μ§ -->>- μ¬μ©μ: μλ΅
Note over μ¬μ©μ, μμ½ κ°λ₯ λ μ§: μμ½ κ°λ₯ν λ μ§
sequenceDiagram
autonumber
actor μ¬μ©μ
μ¬μ©μ ->>+ λκΈ°μ΄: λκΈ°μ΄ μμ²
break λκΈ°μ΄ κ²μ¦ μ€ν¨
λκΈ°μ΄ -->> μ¬μ©μ: 400 Error λ°ν
end
μ¬μ©μ ->>+ μμ½ κ°λ₯ μ’μ: μ½μνΈ μ’μ μ‘°ν μμ²
Note over μ¬μ©μ, μμ½ κ°λ₯ μ’μ: Active ν ν°, μ½μνΈ λ μ§ μ 보
μμ½ κ°λ₯ μ’μ -->>- μ¬μ©μ: μλ΅
Note over μ¬μ©μ, μμ½ κ°λ₯ μ’μ: ν΄λΉ λ μ§μ μμ½ κ°λ₯ν μ’μλ²νΈ
Note over μ¬μ©μ: μ’μ λ²νΈ: 1~50
sequenceDiagram
autonumber
actor μ¬μ©μ
μ¬μ©μ ->>+ λκΈ°μ΄: λκΈ°μ΄ μμ²
break λκΈ°μ΄ κ²μ¦ μ€ν¨
λκΈ°μ΄ -->> μ¬μ©μ: 400 Error λ°ν
end
μ¬μ©μ ->>+ μ’μ μμ½: Active ν ν°, μ’μ μμ½ μμ²
Note over μ¬μ©μ, μ’μ μμ½: μ½μνΈ λ μ§, μ’μ μ 보
μ’μ μμ½ ->> μ’μ μμ½: μ’μ μμ½ μν(lock) λ³κ²½
μ’μ μμ½ -->>- μ¬μ©μ: μ’μ μμ λ°°μ μλ£
Note over μ¬μ©μ, μ’μ μμ½: κ²°μ μ 보, μμ λ°°μ μ ν¨ μκ°
sequenceDiagram
autonumber
actor μ¬μ©μ
μ¬μ©μ ->>+ μμ‘ μΆ©μ : μμ‘ μΆ©μ μμ²
Note over μ¬μ©μ, μμ‘ μΆ©μ : μ¬μ©μ μλ³μ(pk), μΆ©μ ν κΈμ‘
μμ‘ μΆ©μ -->>- μ¬μ©μ: μμ‘ λ°ν
sequenceDiagram
autonumber
actor μ¬μ©μ
μ¬μ©μ ->>+ μμ‘ μ‘°ν: μμ‘ μ‘°ν μμ²
Note over μ¬μ©μ, μμ‘ μ‘°ν: μ¬μ©μ μλ³μ(pk)
μμ‘ μ‘°ν -->>- μ¬μ©μ: μμ‘ λ°ν
sequenceDiagram
autonumber
actor μ¬μ©μ
μ¬μ©μ ->>+ λκΈ°μ΄: λκΈ°μ΄ μμ²
break λκΈ°μ΄ κ²μ¦ μ€ν¨
λκΈ°μ΄ -->> μ¬μ©μ: 400 Error λ°ν
end
μ¬μ©μ ->>+ κ²°μ : κ²°μ μμ²
Note over μ¬μ©μ, κ²°μ : Active ν ν°, κ²°μ μ 보, μ’μ λ°°μ λ²νΈ
κ²°μ ->>+ μ’μ μμ½: μμ λ°°μ 체ν¬
Note over κ²°μ , μ’μ μμ½: μ’μ λ°°μ λ²νΈ
μ’μ μμ½ -->>- κ²°μ : μμ λ°°μ μ¬λΆ
break μ’μ μμ λ°°μ μλ¨ (or λ§λ£ 5λΆ)
κ²°μ -->> μ¬μ©μ: μ’μ μμ λ°°μ μλ¨
end
alt μμ‘ μμ
κ²°μ ->>+ μμ‘ μ‘°ν: μμ‘ μ°¨κ°
Note over κ²°μ , μμ‘ μ‘°ν: μ¬μ©μ μλ³μ(pk)
μμ‘ μ‘°ν -->> κ²°μ : κ²°μ μ±κ³΅
κ²°μ ->> μ’μ μμ½: κ²°μ μλ£
Note over κ²°μ , μ’μ μμ½: μ’μ λ°°μ λ²νΈ
κ²°μ ->> λκΈ°μ΄: λκΈ°μ΄ ν ν° λ§λ£
μ’μ μμ½ -->> μ¬μ©μ: μμ½ μλ£
Note over μ¬μ©μ, μ’μ μμ½: μ’μ λ°°μ λ²νΈ
else μμ‘ μμ
κ²°μ ->>+ μμ‘ μ‘°ν: μμ‘ μ°¨κ°
Note over κ²°μ , μμ‘ μ‘°ν: μ¬μ©μ μλ³μ(pk)
μμ‘ μ‘°ν -->>- κ²°μ : μμ‘ λΆμ‘±
κ²°μ -->>- μ¬μ©μ: μμ‘ λΆμ‘±
end
βββ api
β βββ concert
β β βββ application
β β β βββ DataPlatformSendService.java
β β βββ domain
β β β βββ Concert.java
β β β βββ ConcertRepository.java
β β β βββ ConcertSchedule.java
β β β βββ ConcertSeat.java
β β β βββ ConcertService.java
β β β βββ MockApiClient.java
β β β βββ Payment.java
β β β βββ PaymentOutbox.java
β β β βββ Reservation.java
β β β βββ enums
β β β β βββ ConcertSeatStatus.java
β β β β βββ PaymentOutboxState.java
β β β β βββ PaymentState.java
β β β β βββ ReservationStatus.java
β β β βββ event
β β β β βββ PaymentEventPublisher.java
β β β β βββ PaymentSuccessEvent.java
β β β βββ message
β β β βββ PaymentMessageOutboxManager.java
β β β βββ PaymentMessageSender.java
β β βββ infrastructure
β β β βββ ConcertMapper.java
β β β βββ MockApiClientImpl.java
β β β βββ db
β β β β βββ ConcertEntity.java
β β β β βββ ConcertScheduleEntity.java
β β β β βββ ConcertSeatEntity.java
β β β β βββ PaymentEntity.java
β β β β βββ PaymentOutboxEntity.java
β β β β βββ ReservationEntity.java
β β β β βββ repository
β β β β βββ ConcertRepositoryImpl.java
β β β β βββ JpaConcertRepository.java
β β β β βββ JpaConcertScheduleRepository.java
β β β β βββ JpaConcertSeatRepository.java
β β β β βββ JpaPaymentOutboxRepository.java
β β β β βββ JpaPaymentRepository.java
β β β β βββ JpaReservationRepository.java
β β β β βββ PaymentMessageOutboxManagerImpl.java
β β β βββ kafka
β β β β βββ PaymentKafkaMessageSender.java
β β β βββ spring
β β β βββ PaymentSpringEventPublisher.java
β β βββ interfaces
β β βββ ConcertController.java
β β βββ consumer
β β β βββ PaymentMessageConsumer.java
β β βββ event
β β β βββ PaymentEventListener.java
β β βββ request
β β β βββ BookingSeatsRequest.java
β β β βββ PayRequest.java
β β βββ response
β β βββ BookingSeatsResponse.java
β β βββ PayResponse.java
β β βββ SearchPaymentResponse.java
β β βββ SearchScheduleResponse.java
β β βββ SearchSeatsResponse.java
β βββ user
β β βββ domain
β β β βββ User.java
β β β βββ UserRepository.java
β β β βββ UserService.java
β β βββ infrastructure
β β β βββ JpaUserRepository.java
β β β βββ UserEntity.java
β β β βββ UserRepositoryImpl.java
β β βββ interfaces
β β βββ ChargeRequest.java
β β βββ ChargeResponse.java
β β βββ SearchAmountResponse.java
β β βββ UserController.java
β βββ waiting
β βββ domain
β β βββ WaitingService.java
β β βββ WaitingToken.java
β β βββ WaitingTokenRepository.java
β β βββ enums
β β βββ WaitingTokenStatus.java
β βββ infrastructure
β β βββ RedisLockRepository.java
β β βββ WaitingTokenRepositoryImpl.java
β βββ interfaces
β βββ TokenResponse.java
β βββ WaitingController.java
β βββ event
βββ support
βββ JsonUtil.java
βββ LoggingFilter.java
βββ WaitingInterceptor.java
βββ config
β βββ AsyncConfig.java
β βββ FilterConfig.java
β βββ KafkaConfig.java
β βββ RedisCacheConfig.java
β βββ RedisConfig.java
β βββ WebMvcConfig.java
βββ exception
β βββ BaseException.java
β βββ CustomBadRequestException.java
β βββ CustomNotFoundException.java
β βββ ErrorCode.java
β βββ Exception.java
βββ handler
β βββ ApiControllerAdvice.java
β βββ ApiResultResponse.java
β βββ ErrorResponse.java
β βββ LockHandler.java
β βββ TransactionHandler.java
βββ scheduler
βββ ConcertSeatScheduler.java
βββ KafkaRepublishScheduler.java
βββ WaitingTokenScheduler.java