본문 바로가기

전체 글163

코드 너머, 회사보다 오래 남을 개발자 제목: 코드 너머, 회사보다 오래 남을 개발자저자: 김상기, 배문교, 이동현, 이상아, 이수형, 차지현, 황성재교보문고 링크GitHub 링크목차[PART 1] 상위 1% 개발자가 되기 위한 실전 소프트 스킬CHAPTER 01CHAPTER 02[PART 2] 조직을 성장의 무대로 만드는 커리어 전략CHAPTER 03CHAPTER 04[PART 3] 커리어 도약을 위한 퍼스널 브랜딩 기술CHAPTER 05CHAPTER 06CHAPTER 07FAQ “데브렐, 그게 뭔가요?” 2025. 10. 20.
자바와 JUnit을 활용한 실용주의 단위 테스트 제목: 자바와 JUnit을 활용한 실용주의 단위 테스트저자: 제프 랭어, 앤디 헌트, 데이브 토마스교보문고 링크GitHub 링크목차1부 단위 테스트의 기초1장 첫 번째 JUnit 테스트 만들기2장 JUnit 진짜로 써 보기3장 JUnit 단언 깊게 파기4장 테스트 조직2부 빠른 암기법 습득5장 좋은 테스트의 FIRST 속성6장 Right-BICEP: 무엇을 테스트할 것인가?7장 경계 조건: CORRECT 기억법3부 더 큰 설계 그림8장 깔끔한 코드로 리팩토링하기9장 더 큰 설계 문제10장 목 객체 사용11장 테스트 리팩토링4부 더 큰 단위 테스트 그림12장 테스트 주도 개발13장 까다로운 테스트14장 프로젝트에서 테스트부록 A 인텔리제이 IDEA와 넷빈즈에서 JUnit 설정 2025. 9. 26.
Spring Batch 메타 테이블의 구조와 동작 원리 TL;DR스프링 배치를 처음 실행했을 때, DB에 이상한 테이블들이 주르륵 생기는 걸 보게 됐다.이름도 BATCH_JOB_INSTANCE, BATCH_JOB_EXECUTION 이런 식이라 뭔가 중요한 역할을 하는 것 같았다.그래서 “이 테이블들이 뭘 하는지, 누가 만들고 언제 쓰이는지” 궁금해서 정리해 봤다.어떤 테이블들이 만들어지나?스프링 배치는 Job과 Step 실행 이력을 관리하기 위해 몇 가지 메타 테이블을 자동으로 만든다. 대표적인 건 아래와 같다.BATCH_JOB_EXECUTION: 실제 실행 이력 (시작/종료 시간, 상태, exit code 등)BATCH_JOB_EXECUTION_CONTEXT: Job 실행 컨텍스트 저장소 (재시작 시 필요한 상태값 유지)BATCH_JOB_EXECUTION_.. 2025. 9. 19.
Loop:Pak - 10주간의 회고 TL;DR10주 동안의 루프팩은 단순히 기술 스택을 익히는 시간이 아니었다."어떻게 하면 더 나은 설계와 판단을 할 수 있을까?"를 계속 고민하며, 내 사고방식 자체가 바뀌어 갔던 여정이었다. Loop:PAK - 새로운 코딩 교육의 시작, 루퍼스에서 곧 만나요!루퍼스 부트캠프는 크루원들의 한단계 높은 성장을 이끄는 선순환을 목표로 현업 개발자와 협업하여 새롭게 탄생한 실전 개발 강의입니다. 열정있는 여러분에게, 진심을 다하는 루퍼스가, 진짜www.loopers.im10주간의 성장 회고: 기능 구현을 넘어 사고방식으로Loopers에서 2025.07.12(토) ~ 2025.09.20(토) 동안 진행한 루프팩 백엔드 vol.1 멘토링이 완료되었다.10주간 매주 정해진 주제에 맞춰 학습하고 실습을 진행하며,.. 2025. 9. 19.
WIL - 9주차 회고 Redis를 "캐시"가 아닌 "저장소"로 바라보기이번 주에는 상품 랭킹 기능을 구현하면서 Redis를 단순한 결과 캐시가 아니라 랭킹 전용 데이터베이스로 활용했다.ZSET의 정렬 특성 덕분에 추가 연산 없이 Top-N, 순위, 점수를 바로 조회할 수 있었고, 이는 실시간성과 고동시 동접 처리 요구에 적합했다.배치 리스너 + Zip-Map-Sink메시지를 단건으로 처리하면 동일 상품에 대한 반복 업데이트로 불필요한 쓰기가 발생한다.이를 개선하기 위해 배치 리스너를 도입했고, 배치 내 이벤트를 상품 단위로 집계(Zip), 가중치 점수로 변환(Map), 최소 연산으로 저장(Sink) 하는 패턴을 적용해 효율을 높였다.집계 책임의 분리: Metrics vs. Rankproduct_metrics 집계와 produ.. 2025. 9. 12.
Redis를 사용하여 상품 랭킹 구현하기 TL;DR상품 집계 이후 좋아요·조회수·판매량을 종합한 랭킹 기능이 요구되었다. 단건 처리 대신 배치 리스너와 zip-map-sink 패턴을 도입해 Redis ZSET 연산을 최적화했고, 가중치 기반 점수 계산으로 랭킹 정확도를 높였다. 일별·시간별 TTL 관리와 carry-over 전략을 통해 랭킹 공백 문제를 해결했으며, 상위 100건을 DB에 백업하고 htmx 기반 시뮬레이션을 추가해 안정성과 가시성을 확보했다.들어가며상품 집계(product_metrics) 기능을 구축한 이후, 추가로 상품 랭킹에 대한 요구사항이 생겼다.단순히 이벤트 데이터를 모으는 것에서 그치지 않고, 좋아요 수, 조회수, 판매량을 기준으로 상품의 순위를 매겨야 했다.기본적으로는 일별/시간별 랭킹 기능을 제공해야 했고, 이를 어.. 2025. 9. 12.
WIL - 8주차 회고 이번 주 과제를 통해 카프카(Kafka)를 학습하면서, 단순히 메시지를 주고받는 MQ(Message Queue) 정도로 생각했던 인식이 완전히 바뀌었다.카프카에서 소개하는 분산 이벤트 스트리밍 플랫폼이 어떤 느낌인지 대략적으로라도 느낄 수 있었다.카프카와 MQ 비교처음 카프카를 접했을 때는 RabbitMQ, ActiveMQ처럼 “메시지를 보내고 받는 도구” 정도로만 생각했다.하지만 이번 과제를 진행하면서 카프카의 본질적인 차이점을 알게 되었다.구분MQKafka메시지 저장 방식메시지를 소비하면 큐에서 삭제토픽에 로그 형태로 영속 저장데이터 재처리기본적으로 어려움오프셋을 기반으로 자유롭게 재처리 가능처리 모델단순 메시지 전달스트리밍 플랫폼 + 이벤트 로그확장성제한적분산 시스템 기반, 컨슈머 그룹으로 병렬 처.. 2025. 9. 5.
카프카 메시지 처리와 재시도 정책 카프카를 사용할 때 주의해야 할 점으로 아래 3가지 내용에 대해서 정리해본다.메시지 “처리 완료”의 기준과 Ackenable.auto.commit 설정과 Lag 확인 방법addRetryableExceptions / addNotRetryableExceptions에 따른 재처리 정책 Ack(Offset 커밋)카프카에서 메시지를 처리했다고 보는 기준은 단순히 리스너에서 로직을 통과했다는 게 아니라 오프셋이 커밋됐는가다.커밋이 되지 않으면 브로커 입장에서는 “아직 처리 안 됨” 상태고, 재시도가 발생할 수 있다. Ack Mode는 아래와 같이 4가지 설정이 있으며 각각 특징은 다음과 같다.AckMode동작 방식커밋 시점장/단점RECORD레코드 단위로 처리 후 커밋한 개 레코드 처리 후 바로 커밋안정적, 처리 보.. 2025. 9. 5.
주문/결제 로직에 이벤트를 적용해보자 기존 주문/결제 로직의 문제점기존 구현에서는 주문 생성 → 쿠폰 사용 처리 → 결제 요청 → 재고 차감 → 주문 상태 변경까지의 모든 과정을 하나의 트랜잭션 안에서 처리했다.단일 트랜잭션으로 구현하면 개발은 단순해 보이지만, 실제 운영 환경에서는 다음과 같은 문제점들이 있다.1. 트랜잭션 점유 시간 증가결제 로직에는 외부 PG(Payment Gateway) 연동이 포함된다.PG API 호출은 네트워크 지연과 외부 시스템 응답 시간을 포함하기 때문에, 전체 트랜잭션 점유 시간이 길어진다.그 결과 동시에 여러 주문을 처리하는 상황에서 DB 커넥션 풀을 잠식하거나 락 경합(lock contention)이 발생해 시스템 전체 성능을 저하시킬 수 있다.2. 외부 시스템 장애에 따른 트랜잭션 실패PG 연동 과정에서.. 2025. 8. 29.
WIL - 7주차 회고 이번 주에는 주문/결제 로직을 다시 바라보면서 설계에 대한 사고방식을 바꾸는 경험을 했다.처음 구현 당시에는 “주문 생성부터 결제까지 한 트랜잭션으로 처리하는 게 당연하다”라고 생각했었다.하나의 흐름에서 모든 걸 끝내는 것이 단순하고 깔끔해 보였기 때문이다.역할과 책임에 따라 서비스를 분리했지만, 그래도 여전히 하나의 트랜잭션처음에는 역할과 책임에 따라 서비스와 도메인을 나누는 것에 집중했다.주문, 결제, 재고, 쿠폰 기능을 각각의 서비스로 분리했지만, 트랜잭션 경계까지는 고려하지 않았다는 게 문제였다. 결국 주문 생성 → 쿠폰 사용 → 결제 요청 → 재고 차감 → 주문 완료까지겉으로는 서비스가 분리된 것처럼 보여도, 실제로는 하나의 거대한 트랜잭션이었다.처음에는 결제를 사용자의 포인트로만 처리했기 때문.. 2025. 8. 29.
WIL - 6주차 회고 이번 주에는 외부 결제 시스템(PG) 과의 연동 시, 외부 API 장애나 지연 상황에서도 우리 서비스의 안정성을 보장하기 위한 Resilience를 사용하여 장애 대응 전략을 직접 설계해 봤다."장애"란 무엇인가서비스에서 장애란 사용자가 기대한 기능을 정상적으로 이용하지 못하는 모든 상태를 의미한다.이는 단순히 서버가 다운되는 경우뿐만 아니라, 외부 시스템(PG)에서의 응답 지연, 일시적인 오류, 네트워크 단절 등 사용자 경험에 영향을 주는 모든 문제를 포함한다.왜 장애를 예방하고 대응해야 할까우리는 지금까지 다음과 같은 고민들을 하고 적용해 보면서 우리 서비스의 안정성을 높이려고 했다.1.다양한 상황을 커버하는 테스트 코드 작성2.동시성 제어를 통해 경쟁 상태(race condition) 방지3.멱등성.. 2025. 8. 24.
장애 대응을 위한 Resilience4j 적용 주문 및 결제 기능은 아래와 같은 흐름으로 진행된다.사용자 -> 주문 요청 -> 결제 서비스 -> PG사 API 결제 요청 (결제 시스템) -> 결제 요청 응답 수신 -> 주문 접수 처리 -> PG사 API 결제 callback 수신 (결제 시스템) -> 결제 성공/실패 처리 -> 주문 완료/실패 처리 이때 결제 시스템과 같은 외부 API의 경우 우리가 의도한 대로 항상 정상적인 응답을 보장하지 않는다.따라서 다양한 장애 상황이 발생할 수 있는데,예를 들면 API 호출 실패 (5xx), API 응답 지연 (타임아웃), 일시적 네트워크 장애, PG사 서버 과부하 등등의 오류가 있으며 이는 단순 재시도만으로는 해결되지 않는다. 이러한 상황에서 Resilience4j를 활용하면,외부 API 호출 시 발생할 수.. 2025. 8. 22.
조회 성능 개선을 위한 반정규화 및 인덱스 설계 - Part. 2 - 조회 성능 개선을 위한 반정규화 및 인덱스 설계 - Part. 1- 조회 성능 개선을 위한 반정규화 및 인덱스 설계 - Part. 2 이전 포스팅에 이어 이번에는 검색, 정렬에 대한 요구사항이 추가됨에 따른 쿼리의 성능 비교를 해보려고 한다.상품 목록 조회 시 상품 좋아요 항목이 같이 조회되어야 한다.상품 목록은 브랜드 ID, 상품명으로 검색이 가능해야 한다.상품 목록은 최신순, 좋아요 순으로 정렬이 가능해야 한다. 이번엔 이전과 동일한 조건에서 검색 조건으로 brandId, name, brandId&name 3개의 케이스로 성능을 확인해 본다.브랜드(brand): 100건상품(product): 10만 건사용자(member): 1만 건상품 좋아요(product_like): 1000만 건상품 좋아요 수.. 2025. 8. 18.
조회 성능 개선을 위한 반정규화 및 인덱스 설계 - Part. 1 - 조회 성능 개선을 위한 반정규화 및 인덱스 설계 - Part. 1- 조회 성능 개선을 위한 반정규화 및 인덱스 설계 - Part. 2 이번 포스팅에서는 조회 성능을 개선하기 위한 방법들인 반정규화와 인덱스에 대해 알아본다. "조회"란 무엇인가?1. "조회"라는 건 저장된 정보를 사용자가 요청하여 확인하는 것을 의미한다."정보"는 어디에 저장되는가?1. 정보는 보통 데이터베이스(DB)에 저장된다.2. DB는 내부적으로 메모리(Buffer Pool)와 디스크에 정보를 보관한다.3. 사용자가 정보를 조회하면, DB는 먼저 메모리(Buffer Pool)에서 데이터를 찾는다.4. 메모리에 없으면 디스크에서 읽어오며, 이때 Disk I/O가 발생한다.5. 디스크 접근은 메모리 접근보다 훨씬 느리기 때문에, Di.. 2025. 8. 18.
DB 인덱스 다음 단계, 캐시로 성능 높이기 캐시(Cache)서비스의 성능을 개선하는 방법 중 하나로 캐시(Cache)가 있다.트래픽이 많고, 동일한 데이터 조회가 반복되는 환경에서는 조회 성능을 개선하기 위해 캐시를 효과적으로 사용해 볼 수 있다.하지만 캐시는 단순히 “빠르다”라는 장점만 있는 것이 아니라, 데이터 불일치·스템피드 등 고려해야 할 다양한 문제를 동반한다는 단점도 있다. 캐시를 적용하기 전에 주의할 점캐시는 항상 첫 번째 선택지가 되어서는 안 된다.캐시의 목적은 조회 성능을 높이는 것이지만, 조회 성능을 개선할 방법이 캐시만 있는 것은 아니기 때문이다.먼저 내가 만든 조회 기능, 즉 쿼리 자체가 느린 것은 아닌지 점검해야 한다.DB 인덱스를 활용해 성능을 개선할 수 있는지도 확인해야 한다.또한 애플리케이션 로직에서 불필요한 N+1 .. 2025. 8. 18.