티스토리

Hide
검색하기
블로그 홈

블로그 홈

Hide

hides.kr/m
신고

Github : https://github.com/teamhide

구독자
9
방명록 방문하기
공지 Profile 모두보기

주요 글 목록

  • MSA 환경에서 선착순 쿠폰 발급 설계해보기 개요MSA로 구축된 환경에서 선착순 쿠폰 발급 시스템을 설계해본다. 설계는 프로모션을 담당하는 서버 입장에서 진행하며 실제 쿠폰을 발급하는 서버와 기타 검증을 수행할 수 있는 서버가 따로 존재하는 상황을 가정한다. 또한 휴먼 리소스가 부족한 제한된 상황에서 최소한의 작업만을 통해 기능을 구현해야 한다.쿠폰 잔여 재고 확인, 쿠폰 발급, 발급 대상 검증 등을 프로모션 서버에서만 진행할 수 있다면 굉장히 간단하게 풀어낼 수 있는 문제다. (관련 포스팅 링크) 하지만 프로모션 서버가 해당 책임을 가지고 있지 않은 상황이기에 까다로운 상황이 몇가지 존재한다. 본 포스팅은 이를 해결하기 위한 설계 과정에 대해 기술한다.최초 아키텍처각 서버의 역할을 다음과 같다.Promotion Server: 프로모션 서버는 클라.. 공감수 4 댓글수 0 2024. 8. 14.
  • 광고 시스템 퍼포먼스 튜닝 회고록 요기요 기술블로그에 작성한 글입니다.개요2022년 12월부터 CPS(Cost Per Sale)기반 신규 광고 시스템이 도입되었는데, 서비스를 운영하는 과정에서 발생한 퍼포먼스 이슈와 그에 대한 해결 사례를 간단하게 소개해 드리고자 합니다.배경 지식사례를 소개해 드리기 전 배경지식을 먼저 말씀드리겠습니다. 실제로는 아래에 설명드리는 로직 외에도 추가적인 복잡한 로직이 존재하지만, 설명을 위해 본 포스팅의 주제에 부합하는 핵심 로직들만 설명드린 점 감안해 주시길 바랍니다.신규 광고 시스템의 경우 헥사고날 아키텍처를 기반으로 이루어져 있고, 각 애그리거트(Aggregate)에 속해있는 유즈케이스는 저마다의 역할에 충실하도록 구현되어 있는 상태였습니다.예를 들어 광고/레스토랑/캠페인이라는 3개의 애그리거트가 존.. 공감수 3 댓글수 1 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 __.. 공감수 0 댓글수 0 2022. 11. 17.
  • 동시성을 고려한 쿠폰 재고 시스템 설계 개요 커머스 도메인을 다루는 서비스를 보면 쿠폰을 제공하는 기능이 꼭 하나씩은 존재한다. 선착순으로 진행하는 경우도 있고 그렇지 않은 경우도 있는데, 대다수의 쿠폰은 재고를 가지기 마련이다. 단순하게 생각한다면 DB에 쿠폰의 재고를 저장해두고 유저가 쿠폰을 획득할 때 마다 재고를 하나씩 차감하면 된다고 생각할 수 있는데 여기에는 큰 문제점이 하나 존재한다. 예를 들어 100개의 쿠폰을 발급할 수 있다고 가정해보자. 99개의 쿠폰이 소진되었고 재고가 1개 남은 상태이다. 이때 A라는 유저가 재고를 조회하고 데이터베이스에서는 1개의 재고가 남았다고 알려준다. 그리고 동시에 B유저가 재고 조회를 진행하고 마찬가지로 데이터베이스에서는 1개의 재고가 남았다고 알려준다. 다음으로 A가 쿠폰을 획득함과 동시에 재고를.. 공감수 2 댓글수 0 2022. 7. 28.
  • FastAPI에서 SQLAlchemy Session 다루는 방법 개요 FastAPI는 비동기 프레임워크이다. 내부적으로는 Starlette를 Wrapping한 프레임워크인데 일반적인 동기 프레임워크인 Flask, Django등과는 다른 패러다임을 가지고 있다. 그에 따라 프로덕션 레벨에서 서비스를 운영하며 많은 트러블슈팅이 있었고 그 중 데이터베이스와 통신을 위해 사용하는 SQLAlchemy 라이브러리 또한 큰 이슈가 발생했었다. 기존에는 SQLAlchemy 1.3버전을 사용하고 있었기 때문에 비동기를 지원하지 않았지만 1.4버전부터 AsyncSession을 통한 비동기를 지원하기 시작했고 현재 사내 코드를 마이그레이션 하기위해 개인적인 테스트를 진행하고 있다. 본 포스팅에서는 비동기 프레임워크에 SQLAlchemy를 올바르게 사용하기 위한 트러블 슈팅을 포함하여 최.. 공감수 4 댓글수 1 2022. 3. 23.
  • 당근 서버 밋업 1회 정리 당근마켓 밋업끝나고 게더타운에서 개인적으로 궁금했던 부분들을 당근/배민분들과 나눈 이야기를 정리합니다. 질문. 데이터베이스 테스트는 어떤 형태로 진행하는지. 테이블 DROP/CREATE 및 유즈케이스별 더미데이터를 넣는작업에 시간소모가 너무 크다. - 현재는 디비 테스트는 진행하지 않는다. 예전에는 유즈케이스별로, 예를 들어서 회원가입을 하면 어떠한 푸시알림이 가고 어떤 데이터가 저장되고 하는 일련의 행동자체를 묶어서 테스트했다. (BDD 말하는듯) 이러한 경우 테스트가 한번 돌 때 2시간 정도 걸렸다. - 테스트 데이터는 직접 케이스별로 필요한건 직접 다 넣어줬다. - 조회용 쿼리의 경우 생각해보면 테이블을 날리고 재구성하는 작업이 필요하지않다. 조회에 필요한 데이터가 있다면 해당 쿼리는 디비를 한번띄.. 공감수 0 댓글수 0 2021. 12. 21.
  • FastAPI에서 이벤트 다루는 방법 개요 상황에 따라서 이벤트를 발생시킬 필요성을 느낄 때가 있다. 하나의 메소드가 너무 많은 책임을 가지고 있어서 책임을 분리하고 싶을 경우, 너무 많은 객체와 연관되어 있어서 의존성을 분리하고 싶을 경우 등 이벤트로 처리해야하는 상황이 심심치 않게 발생한다. 스프링의 경우 ApplicationEventPublisher라는 인터페이스가 존재하고 해당 인터페이스를 사용하면 개발자는 별다른 설정을 해줄 필요 없이 이벤트를 발행할 수 있다. (참고: https://hides.tistory.com/1084) 요즘 스프링을 꾸준히 공부하고 있는데, 스프링에는 위처럼 이벤트를 다루는 인터페이스뿐만 아니라 엔터프라이즈 레벨의 아키텍처를 설계할 때 도움이 될만한 기능이 기본적으로, 또는 라이브러리 형태로 제공해주는 경우.. 공감수 3 댓글수 0 2021. 12. 15.
  • FastAPI SQLAlchemy 연동하며 발생한 문제 정리 개요 기존과 다른 패러다임을 가진 비동기 프레임워크 FastAPI와 SQLAlchemy를 연동하는 과정에서 발생했던 문제들과 어떠한 형태로 해결했는지에 대해 다뤄본다. 사전 지식 SQLAlchemy는 scoped_session() 함수를 활용하여 Thread-local한 세션을 생성할 수 있다. 이 때 scopefunc 라는 인자에 특정한 함수를 콜백 형태로 넣어주게 된다면 세션 사용 시 아래와 같은 로직을 통해 세션을 관리하게 된다. session.registry.registry에 키/밸류 쌍의 딕셔너리를 생성한다. scopefunc에 넣어준 함수를 통해 키를 결정하고(가져오고) 해당 값을 통해 session.registry.registry에 접근하여 사용할 세션을 가져와서 사용한다. 추후 sessio.. 공감수 0 댓글수 0 2021. 5. 24.
  • Stripe 결제 시스템 도입하기 1. 개요 기존 해외결제의 경우 아임포트를 통해 페이팔 결제 시스템을 사용하고 있었다. 사용상의 불편함은 없었지만 데이터 분석 결과 나름 치명적인 문제가 하나 발견되었는데, 바로 결제용 팝업 창이 새롭게 뜨는 문제였다. 이게 왜 문제가 되는 걸까? 데이터 분석팀을 통해 유저 행동을 분석해보니 결제창이 뜬 이후 이탈하는 빈도가 굉장히 높은 모습을 찾을 수 있었고, 이 또한 가설이지만 모달/팝업 없이 같은 페이지에서 카드 번호등을 입력하여 결제하는 방식을 제공한다면 보다 높은 결제를 유도할 수 있을 것이라 판단했다. 따라서 결제를 위한 모달 창이나 팝업이 뜨는것이 아닌 임베디드 형태로 페이지내부에 삽입할 수 있는 방법을 찾아보기 시작하였다. 그러다 찾아낸 서비스가 바로 Stripe이다. 이미 해외에서는 유명.. 공감수 7 댓글수 0 2020. 12. 10.
  • Kollus 서비스를 통해 동영상 플랫폼 제작하기 1. 개요 사용자에게 영상을 제공하는 기능이 요구사항으로 등장하였다. 처음으로 살펴본 서비스는 AWS에서 제공하는 미디어 서비스였다. 타 플랫폼을 이용하게되면 해당 플랫폼에서 만든 규칙을 따라야하기 때문에 여러가지 제약사항이 발생할 수 있기에 AWS 서비스를 살펴봤었는데, 몇가지 사항들때문에 직접 구현하지 않기로 결정했다. 첫 번째로, 개발 기간이 늘어난다. 위 요구사항은 언제든지 변할 가능성이 충분한 요구사항이었고 영상을 제공하는 기능 자체는 매니지드 서비스의 장점으로 인해 손쉽게 구현이 가능하겠지만, 한번도 사용해보지 못한 서비스이기 때문에 개발 기간을 정확하게 산정하기가 어려웠다. 두 번째로, 녹화 방지 등 DRM기능이 필요했다. 하지만 그러한 기능까지 서칭하고 구현하기에는 시간적, 비용적인 무리가.. 공감수 4 댓글수 0 2020. 12. 9.
  • Codelog 제작기 1. 개요 나는 시간이 날 때 마다 개발 관련 웹서핑을 한다. 이렇게 간간히 지식을 쌓는 것은 나름 좋은 습관이었는데, 몇가지 문제가 있었다. 각잡고 보는게 아닌 이상 하나의 글을 끝까지 보기가 힘들다는 것이다. 그래서 내 휴대폰 브라우저에는 항상 100개가 넘는 창이 열려있었다. 물론 끝까지 읽은 글들은 절반정도밖에 되지 않는다. 그래서 막연히 생각만 했었다. URL을 모아두는 Repository Site를 하나 만들면 참 좋을 것 같다고. 마침 어떤 토이 프로젝트를 해볼까 고민하던차였고 이번에 만들어보기로 했다. 원래 계획했던 기간은 2일이었는데 역시나 작업을 진행하면서 여러가지 트러블 슈팅을 직면하였고 결과적으로 4일 조금 넘게 걸려 현재는 성공적으로 배포를 완료한 상태이다. 위와 같은 생각의 흐름.. 공감수 3 댓글수 4 2020. 1. 13.
  • Monolithic에서 MSA로의 전환기 1. 개요이전에 다니던 회사의 시스템은 하나의 모놀리틱 서버와 핵심 알고리즘을 수행하는 마이크로 서비스하나로 구성되어 있었다. 또한 PHP로 작성되어 있었는데, 입사 시점과 맞물려 Python으로의 스택 이전과 동시에 특정 도메인을 Microservice Architecture로 분리하는 계획이 잡혀있었다. 돌이켜보면 정말 즐거운 일이었고 챌린징한 업무였기에 많은 성장을 이뤄 냈던 작업이라고 생각한다. 요즘 MSA가 많은 주목을 받으며 인터넷에서도 쉽게 관련 정보를 찾아볼 수 있는데, 실제 실무를 진행하며 느꼈던 점과 과정에 대해 남겨본다. 또한 본 포스팅은 전환했던 과정을 실무 중점적으로 설명하는 포스팅이므로  Monolithic Architecture, Microservice Architecture에.. 공감수 2 댓글수 2 2019. 12. 16.
  • 파이썬 오픈소스 라이브러리 개발기 1. 개요 지금으로부터 약 3주 전, pythondi(https://pypi.org/project/pythondi/) 라는 라이브러리를 개발하여 pypi에 오픈소스로 배포하였다. 그 과정에 대해 간단하게나마 후기를 남긴다. 2. 뭐하는 라이브러리인데? pythondi는 무엇을 하는 라이브러리일까. 이에 대해 설명하기 위해서는 먼저 객체 지향 5대 원칙에 대해서 알아야한다. 이를 앞글자만 따서 SOLID라고 부르는데, 각 스펠링마다의 의미는 다음과 같다. (본 포스팅은 SOLID원칙에 대한 포스팅이 아니므로 간략하게만 설명한다) S: Single Responsibility Principle(단일 책임 원칙) O: Open Closed Principle(개방 폐쇄 원칙) L: Liskov Substituti.. 공감수 6 댓글수 0 2019. 12. 6.
  • Python Dependency Injection 오늘은 SOLID원칙 중 하나인 Inversion of Control(의존성 역전)에 대해 설명하겠다. 의존성 역전을 구현하려면 Dependency Injection라는 기법을 사용해야 한다. 관련 정보를 인터넷에 검색하면 대부분 자바의 스프링 프레임워크 예제가 나온다. 그만큼 스프링에서는 DI를 사용하는것이 일반적이며 널리 알려진 방법중에 하나이다. 하지만 파이썬에 관한 자료는 정말 찾기 힘들다. 인터넷에 공개되어있는 코드를 봐도 DI를 적용한 예제는 현재까지 본적이 없다. 그나마 몇가지 라이브러리들이 존재하긴 하는데, 실제로 내부에서 어떠한 형태로 돌아가는지 파악하기가 힘들어서 직접 구현해보고 그 과정을 이렇게 포스팅으로 남긴다. 먼저 다음과 같은 코드가 있다고 가정해보자. class Repo: de.. 공감수 9 댓글수 0 2019. 11. 9.
    문의안내
    • 티스토리
    • 로그인
    • 고객센터

    티스토리는 카카오에서 사랑을 담아 만듭니다.

    © Kakao Corp.