본문 바로가기

Coding/설계 | 경험14

MSA 환경에서 선착순 쿠폰 발급 설계해보기 개요MSA로 구축된 환경에서 선착순 쿠폰 발급 시스템을 설계해본다. 설계는 프로모션을 담당하는 서버 입장에서 진행하며 실제 쿠폰을 발급하는 서버와 기타 검증을 수행할 수 있는 서버가 따로 존재하는 상황을 가정한다. 또한 휴먼 리소스가 부족한 제한된 상황에서 최소한의 작업만을 통해 기능을 구현해야 한다.쿠폰 잔여 재고 확인, 쿠폰 발급, 발급 대상 검증 등을 프로모션 서버에서만 진행할 수 있다면 굉장히 간단하게 풀어낼 수 있는 문제다. (관련 포스팅 링크) 하지만 프로모션 서버가 해당 책임을 가지고 있지 않은 상황이기에 까다로운 상황이 몇가지 존재한다. 본 포스팅은 이를 해결하기 위한 설계 과정에 대해 기술한다.최초 아키텍처각 서버의 역할을 다음과 같다.Promotion Server: 프로모션 서버는 클라.. 2024. 8. 14.
광고 시스템 퍼포먼스 튜닝 회고록 요기요 기술블로그에 작성한 글입니다.개요2022년 12월부터 CPS(Cost Per Sale)기반 신규 광고 시스템이 도입되었는데, 서비스를 운영하는 과정에서 발생한 퍼포먼스 이슈와 그에 대한 해결 사례를 간단하게 소개해 드리고자 합니다.배경 지식사례를 소개해 드리기 전 배경지식을 먼저 말씀드리겠습니다. 실제로는 아래에 설명드리는 로직 외에도 추가적인 복잡한 로직이 존재하지만, 설명을 위해 본 포스팅의 주제에 부합하는 핵심 로직들만 설명드린 점 감안해 주시길 바랍니다.신규 광고 시스템의 경우 헥사고날 아키텍처를 기반으로 이루어져 있고, 각 애그리거트(Aggregate)에 속해있는 유즈케이스는 저마다의 역할에 충실하도록 구현되어 있는 상태였습니다.예를 들어 광고/레스토랑/캠페인이라는 3개의 애그리거트가 존.. 2023. 7. 19.
SQLAlchemy와 AsyncIO를 사용할 때 발생한 문제점 개요 SQLAlchemy 1.4 비동기 세션을 통해 작업을 진행하던 중 아래와 같은 에러가 발생하였다. if self.session.twophase and self._parent is None: AttributeError: 'NoneType' object has no attribute 'twophase' 이에 대해 조사한 내용을 간단하게 정리한다. 환경 PostgreSQL SQLAlchemy 1.4.42 FastAPI 0.87.0 asyncpg 0.26.0 사전 지식 본 코드에서는 아래와 같은 형태로 비동기 세션을 사용하기 위한 환경을 구성하였다. SQLAlchemyMiddleware import uuid4 class SQLAlchemyMiddleware(BaseHTTPMiddleware): def __.. 2022. 11. 17.
동시성을 고려한 쿠폰 재고 시스템 설계 개요 커머스 도메인을 다루는 서비스를 보면 쿠폰을 제공하는 기능이 꼭 하나씩은 존재한다. 선착순으로 진행하는 경우도 있고 그렇지 않은 경우도 있는데, 대다수의 쿠폰은 재고를 가지기 마련이다. 단순하게 생각한다면 DB에 쿠폰의 재고를 저장해두고 유저가 쿠폰을 획득할 때 마다 재고를 하나씩 차감하면 된다고 생각할 수 있는데 여기에는 큰 문제점이 하나 존재한다. 예를 들어 100개의 쿠폰을 발급할 수 있다고 가정해보자. 99개의 쿠폰이 소진되었고 재고가 1개 남은 상태이다. 이때 A라는 유저가 재고를 조회하고 데이터베이스에서는 1개의 재고가 남았다고 알려준다. 그리고 동시에 B유저가 재고 조회를 진행하고 마찬가지로 데이터베이스에서는 1개의 재고가 남았다고 알려준다. 다음으로 A가 쿠폰을 획득함과 동시에 재고를.. 2022. 7. 28.
FastAPI에서 SQLAlchemy Session 다루는 방법 개요 FastAPI는 비동기 프레임워크이다. 내부적으로는 Starlette를 Wrapping한 프레임워크인데 일반적인 동기 프레임워크인 Flask, Django등과는 다른 패러다임을 가지고 있다. 그에 따라 프로덕션 레벨에서 서비스를 운영하며 많은 트러블슈팅이 있었고 그 중 데이터베이스와 통신을 위해 사용하는 SQLAlchemy 라이브러리 또한 큰 이슈가 발생했었다. 기존에는 SQLAlchemy 1.3버전을 사용하고 있었기 때문에 비동기를 지원하지 않았지만 1.4버전부터 AsyncSession을 통한 비동기를 지원하기 시작했고 현재 사내 코드를 마이그레이션 하기위해 개인적인 테스트를 진행하고 있다. 본 포스팅에서는 비동기 프레임워크에 SQLAlchemy를 올바르게 사용하기 위한 트러블 슈팅을 포함하여 최.. 2022. 3. 23.
당근 서버 밋업 1회 정리 당근마켓 밋업끝나고 게더타운에서 개인적으로 궁금했던 부분들을 당근/배민분들과 나눈 이야기를 정리합니다. 질문. 데이터베이스 테스트는 어떤 형태로 진행하는지. 테이블 DROP/CREATE 및 유즈케이스별 더미데이터를 넣는작업에 시간소모가 너무 크다. - 현재는 디비 테스트는 진행하지 않는다. 예전에는 유즈케이스별로, 예를 들어서 회원가입을 하면 어떠한 푸시알림이 가고 어떤 데이터가 저장되고 하는 일련의 행동자체를 묶어서 테스트했다. (BDD 말하는듯) 이러한 경우 테스트가 한번 돌 때 2시간 정도 걸렸다. - 테스트 데이터는 직접 케이스별로 필요한건 직접 다 넣어줬다. - 조회용 쿼리의 경우 생각해보면 테이블을 날리고 재구성하는 작업이 필요하지않다. 조회에 필요한 데이터가 있다면 해당 쿼리는 디비를 한번띄.. 2021. 12. 21.