아직도 Service에 모든 걸 담고 있나요? — 4 Layered Architecture 도입기
·
카테고리 없음
TL;DR — 3 Layered Architecture에서 Service가 비대해지는 건 구조 문제다. 4 Layered Architecture + ArchUnit으로 계층 규칙을 강제하면 이 문제를 예방할 수 있다.Service가 뚱뚱해지는 구조레거시 코드를 열면 익숙한 광경이 보인다. Service 클래스 하나에 비즈니스 로직이 전부 들어가 있다.3 Layered Architecture — Presentation(Controller), Application(Service), Data(Repository) — 를 따른 결과다. 디렉토리로 보면 controller, service, repository 폴더 안에서 관심사별로 파일이 나뉜다. 여기까지는 문제가 없다.3 Layered 자체가 나쁜 구조는 아니..
성장을 고민하는 개발자들에게... #루퍼스부트캠프 #루프백백엔드
·
카테고리 없음
개발자가 되기까지벌써 개발자라는 직업에 뛰어든 지 어언 2년이 되어갑니다.손으로는 무언가를 예쁘게 만들지 못하던 제가, 머리를 통해 화면 위에 무언가를 만들어내는 재미를 알게 되었습니다. HTML, CSS를 독학하며 시작했고, 개발 전반을 제대로 이해하고 싶어 쌍용 강북 교육센터에서 6개월간 국비교육을 들었습니다. 거기서 Java와 Spring의 기초를 배웠고, 수료 후 혼자 React를 공부하다 지금의 회사에 입사하게 되었습니다.성장하고 싶다는 갈증회사를 다니며 2년간 배운 것도 많았지만, 시간이 지날수록 더 성장하고 싶다는 욕구가 점점 커졌습니다.퇴근 후에는 인프런 강의를 듣고, 사이드 프로젝트에도 참여하면서 나름대로 성장하려 애썼습니다. 하지만 혼자 달리다 보니, 어느 순간부터 이런 생각이 들기 시..
Redis Zset 으로 랭킹시스템 구현하기
·
카테고리 없음
Redis Zset은 랭킹 시스템에 최적화된 자료구조다. 삽입, 조회, 순위 확인 모두 O(log N)의 시간복잡도를 가진다.이 글에서는 세 가지를 다룬다:Zset이 왜 빠른가 — Skip List의 동작 원리어떻게 구현하는가?콜드 스타트 문제 — 일별 랭킹에서 날짜가 바뀔 때 발생하는 문제와 해결책1. 왜 Zset인가?RDB의 한계관계형 데이터베이스에서 랭킹을 조회하려면 ORDER BY를 사용해야 한다. 인덱스가 있더라도 대규모 데이터에서는 부담이 크다. 특히 "내 순위가 몇 등이지?"라는 질문에 답하려면 전체 데이터를 스캔해야 한다.Zset의 강점Redis Zset은 이런 연산들을 제공한다연산명령어시간복잡도점수 추가/갱신ZADDO(log N)특정 멤버 순위 조회ZRANKO(log N)상위 N명 조회Z..
카프카는 그냥 메시지 큐가 아니었다
·
카테고리 없음
TL;DR카프카를 단순한 메시지 큐로 오해했다가, 파티션 키 기반 라우팅, 컨슈머 그룹의 유연성, 트래픽 스파이크 대응이라는 핵심 개념을 학습하며 제대로 이해하게 된 과정카프카는 당연히 메시지 큐라고 생각했다회사에서 EAI 솔루션을 연결할 때도 QUEUE라는 이름으로 카프카를 위치시켰다. RabbitMQ 같은 거겠지, 메시지를 보내고 받는 큐 시스템이겠지 싶었다.그런데 이번에 부트캠프에서 카프카를 제대로 배우면서 알게 됐다. 이건 정확히 맞는 말은 아니었다.솔직히 실무에서 구체적으로 카프카를 깊게 써본 적은 없다. 과제를 할 때도 특정 에러를 겪지 않아서 잘 몰랐다. 하지만 이번 학습을 통해 내가 카프카에 대해 여러 오해를 하고 있었다는 걸 깨달았다.첫 번째 깨달음: 파티션 키가 없으면 순서가 보장되지 ..
트랜잭션을 작게 분리해야 하는 이유와 기준
·
카테고리 없음
TL;DR트랜잭션은 "좁게 잡으라"는 말을 많이 들었지만, 왜 그런지 직접 체감하지 못했다. 이커머스 주문 로직을 리팩토링하면서 트랜잭션 범위에 따른 성능 차이를 테스트해봤더니, 동일 조건에서 약 15배의 성능 차이가 났다. 이 글에서는 트랜잭션 범위를 어떤 기준으로 나눴는지, 그리고 실제 테스트 결과를 공유한다.트랜잭션, 습관적으로 붙이고 있진 않나요?@Transactional 어노테이션, 혹시 습관적으로 붙이고 계신가요?저도 그랬습니다. 이커머스 프로젝트에서 주문 로직을 개발할 때, 하나의 트랜잭션 안에서 모든 걸 처리하고 있었습니다.@Transactionalfun order(userId: Long, command: OrderCommand): OrderModel { // 1. 가격 계산 및 할인..
Circuit Breaker : try-catch 로 충분하지 않은 이유
·
카테고리 없음
TL;DR: 장애 전파 방지는 단순히 에러를 잡는 게 아니다. 단일 요청에서는 try-catch로 충분해 보이지만, 동시에 수많은 요청이 들어올 때는 스레드가 묶이면서 서버 전체가 멈출 수 있다. Circuit Breaker는 "이미 죽은 거 알았으니까 시도도 하지 마"라는 접근으로, 호출 자체를 막아서 스레드를 보호한다.장애 전파 방지 = 에러 핸들링이라고 생각했다외부 API를 호출하는 코드를 작성할 때, 나는 당연히 try-catch로 감싸야 한다고 생각했다. PG사 결제 API를 호출하는데 에러가 나면? catch에서 잡아서 적절한 에러 메시지를 반환하면 된다. 이렇게 하면 PG사에서 문제가 생겨도 우리 서비스가 터지지 않는다. 장애 전파를 막은 거다. 적어도 나는 그렇게 생각했다.그래서 Circu..
읽기 대용량 트래픽, 어떻게 대응하시겠습니까?
·
카테고리 없음
TL;DR: 읽기 대용량 트래픽에 대응하는 사고 흐름은 이렇다. 병목 구간 파악 → 인덱스 확인 → 동기 처리 병목 확인 → 테이블 구조 변경 검토 → 캐시 도입. 경험이 없어도 체계적인 접근 방식을 보여줄 수 있다.도입면접에서 이런 질문을 받는다고 상상해보자."읽기 대용량 트래픽이 들어와서 서버가 다운됐다고 했을 때, 어떻게 대응하시겠습니까?"솔직히 실무에서 대용량 트래픽을 직접 경험해본 적이 없다면 막막할 수 있다. 나 또한 B2B인 지금 회사에서는 대부분의 쓰기 작업이 많을 뿐, 읽기에는 대용량 트래픽이 들어오지 않는다. 하지만, 경험이 없다고 대답을 못하는 건 아니다. 중요한 건 어떤 사고 흐름으로 문제에 접근하는가다.이 글에서는 내가 이 질문을 받았을 때 어떻게 답변할지, 그 사고 과정을 정리해..
100명이 동시에 상품을 구매한다면? - 동시성 문제 직접 테스트해보기
·
카테고리 없음
TL;DR100명이 동시에 같은 상품을 구매하면 재고는 정확히 차감될까? 직접 테스트해본 결과, 아무런 처리 없이는 데이터 정합성이 깨진다. 낙관적 락과 비관적 락으로 해결할 수 있지만, 트래픽이 많은 상황에서 낙관적 락은 비관적 락보다 약 5배 느렸다. 언제 어떤 락을 써야 하는지 실험을 통해 기준을 세웠다.100명이 동시에 상품을 구매한다면?100명이 동시에 같은 상품을 구매한다면, 재고는 어떻게 될까? 1000개의 재고가 있을 때, 100명이 구매하면 당연히 900개가 남을 것으로 예측한다. 현실에서도 그렇고, 코드에서도 그래야 한다. 하지만, 멀티스레드 환경에서는 예상과 다른 일이 벌어진다.간단해 보이는 이 작업이 실제로는 다음 과정을 거친다:시간 순서:1. Thread A: 재고 읽음 (1000..
좋아요 수는 Product 테이블에 넣어야 할까? - 정규화 vs 비정규화 트레이드 오프
·
카테고리 없음
정규화와 비정규화는 Read/Write 트레이드 오프다. 테이블을 나누면, fetch join 비용이 증가하지만, Write Lock 이 분산된다. 서비스 특성에 따라 선택하되, 그 이유를 설명할 수 있어야 한다. 시작하며상품 서비스를 설계하면서 고민이 생겼다. Product 엔티티를 설계하는데, 상품 자체의 정보뿐만 아니라 어떤 브랜드의 제품인지, 현재 재고가 몇 개 남았는지, 몇 명이 좋아요를 눌렀는지, 몇 명이 리뷰를 남겼는지 같은 정보들도 함께 관리해야 했다. 이것들을 어떻게 관리해야 할까?A안은 Product 테이블에 모든 정보를 포함하는 것이었다. 단순하고 직관적했다. 하나의 테이블로 모든 정보를 관리할 수 있었다.CREATE TABLE product ( id BIGINT, name..
WIL - 2주차 [소프트웨어 디자인]
·
카테고리 없음
유비쿼터스 언어의 중요성유비쿼터스 언어란 도메인 전문가와 개발자가 함께 만들고 사용하는, 코드에도 그대로 반영되는 공통 언어를 말합니다. 이번 주에 유비쿼터스 언어라는 개념을 처음 접했습니다. 단순히 회의실에서만 쓰는 용어가 아니라, 실제 코드의 변수명, 클래스명까지 동일하게 가져가는 게 핵심이었습니다.실제로 현재 개발 중인 임장(부동산 임장) 앱에서 이 문제를 크게 체감했습니다. '임장'이라는 용어 자체가 영어로 대응되는 단어가 없다 보니, 개발 초반엔 Limjang으로 코딩하다가 중간에 Note로 바꾸기도 했고, PM과 대화할 때는 '마이노트', '공유노트', '임장' 등 각자 다른 용어를 사용했습니다.겪었던 문제: 임장과 노트, 불분명한 도메인 언어특히 팀에 처음 합류했을 때 이런 용어들 때문에 적..