Kafka, 제대로 이해하고 쓰자
이커머스 프로젝트에서 주문 후 알림을 비동기로 분리할 때 Kafka를 처음 썼습니다. kafkaTemplate.send() 한 줄이면 메시지가 날아갔고, @TransactionalEventListener로 트랜잭션 커밋 후에만 발행하게 했습니다. 동작은 했는데, 누가 “Kafka에서 메시지 순서가 보장돼?” 하고 물으면 선뜻 대답을 못 하겠더라고요. ...
이커머스 프로젝트에서 주문 후 알림을 비동기로 분리할 때 Kafka를 처음 썼습니다. kafkaTemplate.send() 한 줄이면 메시지가 날아갔고, @TransactionalEventListener로 트랜잭션 커밋 후에만 발행하게 했습니다. 동작은 했는데, 누가 “Kafka에서 메시지 순서가 보장돼?” 하고 물으면 선뜻 대답을 못 하겠더라고요. ...
“운동화를”로 검색하면 “운동화”가 안 나왔습니다. 이커머스 프로젝트의 상품 검색은 MySQL LIKE '%keyword%'로 구현되어 있었습니다. 키워드가 상품명에 포함되어 있으면 결과가 나오고, 아니면 0건. 단순했고, 처음에는 충분했습니다. 문제는 한글이었습니다. “운동화를”에서 조사 “를”이 붙으면 “운동화”와 다른 문자열이 됩니다. MyS...
백엔드 41개 API를 만들어놓고 iOS 앱을 열어보니, 모든 화면이 하드코딩된 MockData로 돌아가고 있었습니다. 친구 목록도, 약속도, 알림도 앱을 재시작하면 항상 같은 데이터. 여기서부터가 진짜 시작이었습니다. MockData 지옥에서 탈출하기 화면은 있는데 데이터가 가짜다 iOS 앱의 모든 ViewModel이 이런 식이었습니다. cl...
친구들과의 약속에 늦을 때마다 “출발했어?” 카톡이 오고, 이동시간을 매번 검색하는 게 귀찮아서 앱을 만들기 시작했습니다. 약속 시간에서 이동시간을 역산해서 “지금 출발해”라고 알려주는 앱, 오디야(어디야)입니다. 3주 반 동안 41개 API와 6종의 스케줄러를 구현하면서, “이게 맞나?” 싶은 순간이 반복됐습니다. 외부 API를 매번 호출하면 무...
이커머스 플랫폼을 처음부터 만들었습니다. 기능을 구현할 때마다 “이게 맞나?” 싶은 순간이 반복됐고, 처음에 돌아가던 코드가 깨지는 상황을 만나면서 하나씩 고쳐나갔습니다. 재고 차감에서 시작된 동시성 고민 단순한 코드가 깨지는 순간 처음 주문 기능을 만들 때, 재고 차감은 별 생각 없이 구현했습니다. product.decreaseStock(qua...
왜 만들었나 PRD 쓰고, 설계하고, 구현하고, 리뷰 받고, 커밋하고, PR 올리고. 매번 같은 사이클이었습니다. Claude Code를 쓰면서 각 단계를 자동화할 수 있겠다는 생각이 들었고, 그걸 하나의 플러그인으로 묶어보고 싶었습니다. Claude Code에는 스킬(Skill)이라는 시스템이 있습니다. .claude/skills/ 디렉토리에 마...
하네스 엔지니어링이란 LLM 에이전트에게 코드를 작성하게 할 수 있습니다. 그런데 작성하면 안 되는 코드도 작성할 수 있다는 게 문제입니다. 하네스 엔지니어링은 AI 에이전트의 행동 범위를 설계하고 제한하는 기법입니다. 프롬프트 엔지니어링이 “뭘 하라”를 잘 전달하는 기술이라면, 하네스 엔지니어링은 “뭘 하지 마라”를 시스템 수준에서 강제하는 기술...
시작하며 10주가 끝났습니다. Loopers라는 이름처럼 반복하고, 부수고, 다시 쌓았습니다. 매주 새로운 문제를 마주했고, 매주 다른 방식으로 틀렸습니다. 그 과정을 돌아봅니다. Week 1-3: 설계의 중요성 Facade 패턴과 계층 분리 처음 3주는 설계에 대한 감을 잡는 시간이었습니다. Facade 패턴을 처음 접했을 때는 왜 이렇게 ...
인기 상품 랭킹 시스템 요구사항 실시간으로 인기 상품 TOP 10을 보여줍니다 인기도 기준: 조회수, 좋아요, 주문 수를 가중치를 두어 합산 일간 집계 기준 (오늘 발생한 이벤트만 반영) Redis Sorted Set (ZSET) 선택 랭킹 시스템에 Redis ZSET을 선택한 이유입니다. ZADD: O(log N)으로 점수...
ApplicationEvent의 한계 지난 주 ApplicationEvent로 트랜잭션을 분리했습니다. 그런데 이 구조의 한계가 명확해졌습니다. 1. 메모리 기반 - 서버 재시작 시 유실 이벤트가 메모리에만 존재합니다. 이벤트를 발행하고 핸들러가 처리하기 전에 서버가 재시작되면 이벤트는 사라집니다. 2. 순서 보장 없음 비동기 핸들러가 여러 ...