본문 바로가기

분류 전체보기

(117)
선착순 처리 기능 구현에 대한 고민 '요청을 선착순으로 처리하는 기능을 설계한다면 어떻게 할 것인가' 최근에 면접을 보면서 받았던 질문 중 하나다. 그때 당시에는 바로 든 생각은 단순하게 '트랜잭션 처리해서 결과를 보장하도록 구현하면 되지 않나'라고 생각했던 거 같다. 이걸 어떤 식으로 접근해야 할지 감이 안 와서 제대로 답은 못했고 그냥 '락 걸어서 처리하면 되지 않을까'라는 식으로 대답했다. 면접을 봐주셨던 개발자분께서 설명해 주시면서 레디스 관련 이야기도 나왔는데, 뒤에서 이 방식에 대해 정리를 하려고 하고, 그전에 간단하게 생각했던 DB 트랜잭션을 사용해서 구현하는걸 좀 더 구체적으로 정리해보려고 한다. DB 트랜잭션 사용 처음 생각했을 때는 단순하게 요청 들어오는 대로 즉시 하나씩 처리하면 되지 않을까? 락걸면서?라고 생가했지만 ..
의존성 주입(그리고 부트스트래핑) 13.2 명시적 의존성은 완전히 이상하고 자바스러운가? 파이썬에서는 의존성을 처리하는 표준 방법은 임포트를 통해 모든 의존성을 암시적으로 선언함. 테스트를 위해 무언가를 바꿔야 한다면 동적 언어인 파이썬에서는 멍키 패치를 할 수 있음. 그니까 모킹 해서 테스트할 수 있다는 거임. 근데 이게 모킹 한 모든 테스트마다 mock.patch 같은 걸 호출해야 함. 그리고 이러한 코드는 구현이랑 밀접하게 묶어줌. 그니까 나중에 리팩터링으로 모킹 하는 함수를 수정하면 다 수정할 수도 있음. 따라서 이 또한 트레이드오프임. 명시적 의존성을 사용하면 애플리케이션이 더 복잡해질 수도 있음. 하지만 테스트를 더 쉽게 작성하고 관리할 수 있다고 함. 그리고 명시적 의존성 정의는 의존성 역전 원칙의 예라고 함. 구체적인 세부..
명령-질의 책임 분리(CQRS) 논란의 여지가 없는 부분, 읽기(질의)와 쓰기(명령) 은 다르다. 다르게 취급해야 함. 근데 왜 이렇게 해야 하나? 이전에 짧게 봤던 개념인데 여기서 구체적으로 구현하는 방식 중 하나를 소개한다. 하지만 책에서 소개하는 방법은 같은 프로세스, 같은 DB 내에서 구현하는 방식을 소개함. 거기서 테이블 정도만 달라지는 방식. 12.1 쓰기 위해 존재하는 도메인 모델 지금까지 했던, 작업단위, 애그리게이트, 이벤트 패턴등은 상태를 변경할 때 규칙 적용을 강화하기 위해 존재한다. 즉 데이터를 유연하게 쓰기 위해서 도구를 만들었던 것임. 그런데 읽기는 좀 다름 12.2 가구를 구매하지 않는 사용자 결론적으로 무엇을 해도 현실은 소프트웨어 시스템과 일관성이 없다고 함. 그래서 비즈니스 프로세스가 모든 경우를 처리할..
커맨드와 커맨드 핸들러 가존에 애플리케이션의 유스케이스들을 전부 이벤트 핸들러로 변경하면서 새로운 배치 만드는 함수 같은 것들도 이벤트를 만들어서 처리함. 이게 직관적으로 보면 약간 어색해 보임. 배치가 생성도 안 됐는데 api를 호출하는 것도 이상함. 이벤트와 같은 메시지 버스를 다루지만 약간 다른 규칙으로 처리하는 커맨드를 도입함 대략 보니까 기존에 이벤트로 하던걸 커맨드라고 따로 빼서 원래 필요한 서비스작업들을 커맨드로 실제 이벤트로 처리하려 했던 것들을 이벤트로 남김. 커맨드도 메시지의 일종임. 다만 중요한점은 커맨드는 한 행위자로부터 다른 구체적인 행위자에게 전달됨. 명령형 동사구를 사용함. 커맨드는 의도를 잡아냄. 그래서 커맨드를 보내는 행위자는 커맨드 수신자가 커맨드 처리에 실패했을 때 오류 정보를 돌려받길 원함...
GKE 기반 쿠버네티스와 GitHub Actions으로 배포 자동화 언제 한번 프로젝트를 하게 된다면 쿠버네티스로 배포 한번 해야겠다고 생각하고 있었는데, 이번에 Meet-Up-Spot 개인프로젝트 하면서 경험 삼아해 봤다. 목표 자체가 쿠버네티스 개념적인 공부라기 보단 서비스 배포 자동화를 클라우드 환경을 사용해서 하는 것이었기 때문에 필요한 것들만 최소한으로 적용시켜 보았다. 아예 처음부터 CI/CD를 적용해 본 적이 없어서 배포도 좀 걸릴 거라 생각하긴 했는데, 생각보다 오래 걸렸다. 하면서 좀, 트러블 슈팅이라 할거 까진 없지만, 시간이 걸렸던 것들 위주로 정리해보려고 한다. 계획했던 구조는 다음과 같다.  사실 쿠버네티스 매니패스트 파일 작성하는 부분도 처음 하는 작업이여서 오래 걸리긴 했지만 워낙 찾아보면 자료들이 많아서 내가 계획했던 정도는 쉽게 작성한 거..
메시지 버스로 통합하기 이번 장에서 하려는 목표 9.2 서비스 함수를 메시지 핸들러로 리팩터링하기 그전 섹션에서 설명이 나와있지만 기존에 서비스에서 하던걸 전부 핸들러로 바꾼다 어차피 내부적으로 이벤트발생으로 처리하는 거나 엔드포인트에서 핸들러로 처리하는 거나 로직이 차이가 없음. 그리고 여기서 보면 엔드포인트에서 원시값으로 서비스 함수를 호출하던 게 핸들러로 바뀌면서 이벤트 객체로 묶여서 넘김. 그럼 저번에 언급했던 부분이 생각이 남. 객체로 보내던걸 원시 타입으로 바꿨는데 그걸 다시 객체로 묶으면 의존성이 생기는 거 아니냐? 그거에 대한 답변을 책에서 해줌 > 도메인 객체에서 기본 타입에 대한 집착을 거쳐 인터페이스로 이벤트를 사용하기까지 > OO사이클에서 사람들은 기본 타입에 대한 집착을 안티패턴으로 간주한다. 공개 AP..
오브젝트. Chapter 01 객체,설계 이전에 오브젝트 책 읽은 거 복습하면서 정리를 하는데 1장 부분의 코드나 설명들이 책의 전반적인 내용이 담겨있어서 정리해 봤다. 개념보다는 실무가 더 중요하다. 유지보수와, 설계에 관한 한 지금까지는 그러하다. 그리고 소프트웨어 규모가 커지면 커질수록 소프트웨어 설계 분야에서 이론이 실무를 추월할 가능성은 희박해 보임. 아무튼 저자는 이 책에서 좀 더 '코드'에 대해서 더 다룰 거임 01. 티겟 판매 애플리케이션 구현하기 전체적인 첫 구조는 다음과 같음 예제 코드 따로 자바로 올려져 있어서 나는 파이썬으로 작성함. 필요하다면 나중에 자바로 적긴 할 거임. class Audience: def __init__(self, bag): self.bag = bag def getBag(self): return sel..
외부 API 결과에 캐싱 도입 Meet-Up-Spot이라는 프로젝트를 하면서 레디스로 캐싱 메커니즘을 도입한 과정을 기록하려고 한다. 우선 진행하는 프로젝트의 메인 기능이 여러 주소의 중간 지점을 계산해 여러 장소를 추천하는 것이다 보니. 중간 과정에서 몇 번 Google Maps API 요청을 보낸다. 그래서 왜 캐싱을 하려고 하냐면 그냥 생각해 봤을때는 일단 비용적인 문제도 있기 때문에 캐싱하면 좋을 거 같다고 생각함. 또한 api 요청을 줄이면 다른 로직들은 복잡하지 않아서 충분히 성능면에서 나아질거라 판단했다. 그리고 자주 사용될 엔드포인트가 장소 추천일 텐데 , 이게 중간에 좌표를 기준으로 Google Maps API 요청을 보냄, 사실 좌표라는 게 딱 맞기가 힘듦. 근데 그 주변 좌표들을 요청하면 어차피 거기서 거기엔 장소..