Neo4j와 그래프 DB — 관계가 핵심일 때 RDB를 버려야 하는 이유
“친구의 친구의 친구 중에서 나와 같은 도시에 살면서 비슷한 음악 취향을 가진 사람을 찾아라.” 관계형 DB로 이 쿼리를 작성하면 JOIN이 몇 개나 필요할까? 그래프 DB는 이 질문에 자연스럽게 답한다. 관계...
“친구의 친구의 친구 중에서 나와 같은 도시에 살면서 비슷한 음악 취향을 가진 사람을 찾아라.” 관계형 DB로 이 쿼리를 작성하면 JOIN이 몇 개나 필요할까? 그래프 DB는 이 질문에 자연스럽게 답한다. 관계...
Cassandra는 “절대 멈추지 않는 DB”를 목표로 설계됐다. 마스터 노드가 없고, 모든 노드가 동등한 역할을 수행하며, 노드 한 대가 죽어도 쓰기와 읽기가 계속된다. 이 글은 그 내부 구조를 링(Ring)...
시스템이 지금 이 순간 무엇을 하고 있는지 알지 못한 채 운영하는 것은, 계기판 없이 비행기를 모는 것과 같다. Prometheus와 Grafana는 그 계기판을 만드는 도구다. 메트릭 수집, 저장, 시각화, ...
하루에 10억 줄의 로그가 쌓인다면 어떻게 될까. 파일에 그냥 쓰면 수 TB가 되고, 검색은 불가능해진다. 로그 파이프라인은 이 데이터를 실시간으로 수집하고, 가공하고, 저장해서 밀리초 단위로 검색 가능하게 만...
Java 개발자가 Kotlin으로 넘어올 때 마지막까지 Java 방식을 고집하는 영역이 있다. 바로 테스트다. JUnit 5와 Mockito는 익숙하고 문서도 많다. 그런데 막상 Kotlin 코드를 Mockit...
Kotlin 코드베이스를 처음 읽을 때 가장 낯선 것이 두 가지다. 하나는 ?.let { }, apply { }, also { } 같은 스코프 함수들이 뒤엉켜 있는 체이닝 코드고, 다른 하나는 val token...
리액티브 프로그래밍의 핵심은 “값이 언제 올지 모를 때 그 흐름을 다루는 방식”이다. RxJava는 Observable로, Reactor는 Flux/Mono로 이를 구현했다. Kotlin은 코루틴 위에 Flow...
Java에서 컬렉션 처리 코드를 작성하면 for 루프, 임시 변수, null 체크가 뒤엉켜 20줄이 넘어가는 경우가 흔하다. Kotlin은 그 코드를 3줄로 줄이고, 타입 안전성과 null 안전성을 유지하면서 ...
Spring Data JPA를 쓰면서 JpaRepository가 어떻게 구현체 없이 동작하는지 궁금했던 적이 있다면, 이 글이 그 궁금증을 해소해준다. 인터페이스를 선언하면 알아서 동작하는 마법의 원리부터 Sp...
JPQL 쿼리를 문자열로 작성하다 오타 하나에 런타임 예외를 만난 경험이 있다면, QueryDSL이 왜 필요한지 바로 이해할 수 있다. QueryDSL은 컴파일 시점에 쿼리 오류를 잡아주는 타입 세이프 쿼리 빌...
구조 패턴(Structural Pattern)은 클래스와 객체를 어떻게 조합할 것인가에 집중한다. 기존 코드를 건드리지 않고 새 인터페이스를 끼워 넣거나(Adapter), 기능을 동적으로 덧씌우거나(Decora...
생성 패턴(Creational Pattern)은 객체를 어떻게 만들 것인가에 집중한다. new 키워드를 직접 쓰는 대신, 생성 로직을 캡슐화해서 코드가 구체 클래스에 의존하지 않도록 만드는 것이 핵심 목표다. ...
데이터베이스 서버가 한 대뿐이라면, 그 서버가 멈추는 순간 서비스 전체가 멈춘다. MySQL 복제는 이 단일 장애 지점(SPOF)을 없애기 위한 핵심 메커니즘이다. 단순히 백업용 서버를 한 대 더 두는 개념에서...
쿼리가 느리다는 신고가 들어왔다. 로그를 보면 SELECT 하나가 3초를 넘기고 있다. 어디서 시간이 소비되는지 모른 채 인덱스를 마구 추가하거나, 쿼리를 감으로 바꾸는 것은 도박이다. MySQL의 EXPLAI...
서비스가 운영 중인 데이터베이스의 스키마를 바꾸는 일은 달리는 기차 위에서 바퀴를 교체하는 것과 같다. 기차를 멈추면(서비스 중단) 간단하지만, 대부분의 서비스는 그 선택지가 없다. 무중단으로 스키마를 변경하는...
인프라를 손으로 클릭해서 만들던 시대는 끝났다. 클릭으로 만든 서버는 누가, 언제, 어떤 설정으로 만들었는지 아무도 모른다. 이것이 IaC(Infrastructure as Code)가 등장한 이유다.
“서버리스”라는 이름은 반은 거짓말이다. 서버가 없는 게 아니라, 서버를 내가 관리하지 않는다는 뜻이다. 하지만 그 차이가 개발 방식을 근본적으로 바꾼다.
“고양이 사진 보여줘”를 검색하면 파일명에 “고양이”가 없는 사진도 찾아주는 검색엔진이 있다. 반면 기존 키워드 검색은 “고양이”라는 단어가 정확히 일치해야만 결과를 내놓는다. 이 차이가 임베딩과 벡터 DB에서...
데이터 과학자가 노트북에서 95% 정확도를 달성한 모델을 만들었다. 그런데 이것을 초당 1만 건의 요청을 처리하는 프로덕션 서비스에 올리면 어떻게 될까? 십중팔구 레이턴시 폭발, 메모리 부족, 그리고 3개월 후...
LLM에게 “오늘 날씨 알려줘”라고 물으면 그냥 대답한다. 그런데 “내 캘린더에서 오늘 일정 꺼내서, 날씨 API 조회하고, 적절한 옷차림까지 추천해”라고 하면? 단순한 텍스트 생성이 아닌 계획 수립 → 도구 ...
데드락 발생 원리부터 InnoDB 내부 메커니즘, 탐지/예방 전략, 실전 트러블슈팅까지
CAP 정리부터 워크로드 분석, 데이터 모델링, 확장 전략까지 — 시니어 개발자의 DB 선택 프레임워크
테스트 코드는 프로덕션 코드만큼 중요합니다. 잘 작성된 테스트는 리팩토링의 안전망이고, 버그의 조기 감지망이며, 살아있는 명세서입니다. JUnit 5는 JUnit 4와 비교해 아키텍처부터 Extension 모델...
한 줄 요약: 인증/인가 시스템의 핵심은 Access Token의 수명을 짧게 유지하고, Refresh Token을 Rotation시키며, 탈취 시 즉시 무효화할 수 있는 블랙리스트 체계를 갖추는 것이다.
비유로 먼저 이해하기: 음식점에 비유하면, 동기 블로킹은 주방에서 요리가 완성될 때까지 홀 직원이 그 자리에 서서 기다리는 것이다. 비동기 논블로킹은 주문을 넣고 다른 테이블 서빙을 하다가, 주방에서 벨이...
왜 어노테이션 동작원리를 알아야 하는가
한 줄 요약: Entity는 DB의 거울이고, DTO는 계층 간 택배 상자이며, VO는 값 그 자체가 정체성이고, DAO는 SQL 창고 관리인이며, Repository는 도메인이 말하는 컬렉션이다. 이 다...
한 줄 요약: Redis 트랜잭션(MULTI/EXEC)은 클라이언트 출력 버퍼에 명령을 큐잉하고 EXEC 시 원자적으로 실행하지만 롤백이 없다. 진짜 안전한 동시성 제어는 WATCH(CAS)와 Lua Sc...
JPA는 편리한 추상화지만 그 추상화 아래에서 어떤 일이 벌어지는지 모르면 조용히 데이터베이스를 폭격합니다. 주문 목록 100건에 쿼리 101번, 읽기 API가 더티 체킹 스냅샷을 만들고, IDENTITY 전략...
한 줄 요약: Record는 “데이터를 운반하는 투명한 캐리어”를 만들기 위해 Java 16에서 정식 도입된 언어 구조체로, 컴파일러가 필드·접근자·equals·hashCode·toString을 자동 생성...
한 줄 요약: HashMap은 h ^ (h >>> 16) 보조 해시로 비트를 섞고, (n-1) & hash 비트 AND로 버킷 인덱스를 구하며, 충돌이 8개를 넘으면 Red-Blac...
결제 서버에서 HashMap을 공유 캐시로 사용했다. 트래픽이 몰린 순간 CPU가 100%에 박히고 모든 응답이 멈췄다. GC 로그에는 이상이 없었다. 원인은 Java 7 HashMap의 resize() 과정에...
행동 패턴(Behavioral Pattern)은 객체 간의 책임 분배와 알고리즘 교환을 다루는 디자인 패턴 군입니다. 생성·구조 패턴이 “어떻게 만들고 조합하는가”를 다룬다면, 행동 패턴은 “어떻게 협력하고 소...
실생활 비유: 건물 설계와 아키텍처의 공통점
실생활 비유: 쇼핑몰을 DB 중심으로 설계하면 생기는 일
한 줄 요약: 비로그인 임시 장바구니를 Redis에 보관하고, 로그인 시 병합 전략(수량 합산 vs 로그인 우선)으로 충돌을 해소하며, 재고는 결제 시점에만 잠그는 것이다.
한 줄 요약: 리뷰 시스템의 핵심은 베이지안 평균으로 소수 리뷰의 왜곡을 막고, Wilson Score로 유용한 리뷰를 정렬하며, 하이브리드 스팸 탐지 파이프라인으로 가짜 리뷰를 걸러내는 것이다.
한 줄 요약: 추천 시스템의 핵심은 협업 필터링으로 숨겨진 취향을 발굴하고, 2단계 파이프라인(후보 생성 → 정밀 랭킹)으로 수억 개 상품을 100ms 안에 걸러내며, 콜드 스타트와 인기 편향을 동시에 해...
한 줄 요약: 쓰기는 RDB로 정확하게, 읽기는 Elasticsearch와 Redis로 빠르게 분리하고, 멀티테넌트 구조로 수백만 셀러의 상품을 격리하면서 단일 검색 인덱스로 통합 제공한다.
한 줄 요약: 시니어는 “무엇을 쓰느냐”가 아니라 “왜 쓰느냐”를 설명한다. MySQL을 고른 이유, Saga를 고른 이유, CQRS를 고른 이유 — 모든 결정에 WHY가 있어야 면접을 통과한다.
한 줄 요약: MySQL은 ACID로 재고 불변식을 강제하고, Redis는 원자 DECR로 동시 차감 경쟁을 차단하며, Kafka는 비동기 분리로 확정 지연을 흡수한다. 세 계층이 각자의 역할을 맡아야 초...
한 줄 요약: 배송 시스템의 핵심은 실시간 위치 추적으로 고객 불안을 제거하고, 최근접 창고 선택으로 리드타임을 단축하며, 이벤트 소싱으로 배송 상태 이력을 완전하게 보존하는 것입니다.
한 줄 요약: 쿠폰 시스템의 핵심은 Redis 원자 연산으로 초과 발급을 막고, 룰 엔진으로 할인 조합을 유연하게 계산하며, 멀티 어카운트 어뷰징을 사전에 차단하는 것이다.
한 줄 요약: Redis Streams는 “메시지를 보내고 받는 우체통”인데, 받는 사람이 여러 명이어도 편지가 사라지지 않고, 누가 읽었고 누가 아직 안 읽었는지까지 추적해주는 Redis의 자료구조입니다...
한 줄 요약: Redis는 단일 프로세스(Standalone)에서 시작해 자동 장애복구(Sentinel), 수평 확장(Cluster)으로 진화하며, 각 모드는 해결하는 문제가 근본적으로 다르다 — 무엇을 ...
테스트를 작성할 때 “그냥 Mock 쓰면 되지”라고 생각하기 쉽다. 하지만 Mock은 테스트 더블의 다섯 가지 유형 중 하나일 뿐이다. Dummy, Stub, Spy, Mock, Fake는 각각 다른 목적을 가...
단위 테스트가 1000개 통과해도 실제 DB 연결에서 터지면 서비스는 장애다. 통합 테스트는 부품이 아니라 조립된 기계가 돌아가는지 확인하는 테스트다. 이 글에서는 Spring Boot 환경에서 통합 테스트를 ...
한 줄 요약: YouTube의 핵심은 업로드된 영상을 DAG 기반 트랜스코딩 파이프라인으로 해상도별 분할 처리하고, HLS/DASH ABR로 네트워크 상황에 맞게 스트리밍하며, 글로벌 CDN으로 지연시간을...
한 줄 요약: 결제 시스템의 핵심은 세 가지다. 멱등성 키로 이중 결제를 원천 차단하고, 복식부기로 1원 단위 자금 무결성을 보장하며, PG 추상화 레이어로 벤더 장애를 투명하게 폴백한다. 이 세 가지를 ...
한 줄 요약: 위치 기반 서비스의 핵심은 Geohash로 2차원 좌표를 1차원 문자열로 변환하여 B-Tree 인덱스로 근접 검색하고, Redis + Pub/Sub로 라이더 위치를 실시간 전파하는 것이다.
2024년 블랙프라이데이, 아마존의 DynamoDB는 초당 1억 건 이상의 요청을 처리했다. Redis는 단일 노드에서 초당 100만 QPS를 넘긴다. 이 숫자들이 가능한 이유는 단순한 “빠른 하드웨어” 때문이...
한 줄 요약: 분산 파일 저장소의 핵심은 파일을 4MB 블록으로 쪼개 SHA-256 해시로 중복을 제거하고, 메타데이터 DB로 블록 조각을 추적하며, SSE/WebSocket으로 여러 디바이스에 변경을 실...
한 줄 요약
한 줄 요약
한 줄 요약
“상품명에 ‘무선 이어폰’이 포함된 결과를 0.05초 안에 보여줘야 합니다.” RDBMS의 LIKE '%무선 이어폰%'은 100만 건에서 수 초가 걸린다. Elasticsearch는 역인덱스(Inverted I...
전송 계층(Transport Layer)의 두 프로토콜인 TCP와 UDP는 인터넷의 근간이다. 단순히 “TCP는 신뢰성, UDP는 속도”라는 수준을 넘어, 내부 메커니즘이 왜 그렇게 설계됐는지를 이해해야 장애 ...
브라우저 주소창의 자물쇠 아이콘은 단순한 장식이 아니다. 그 뒤에는 수십 년간 발전해온 암호학 프로토콜, 수천 개의 CA와 수억 개의 인증서, 그리고 수없이 반복된 해킹 사고를 통해 다듬어진 신뢰 체계가 존재한...
Google SRE가 정의한 4대 골든 시그널(Latency, Traffic, Errors, Saturation)을 중심으로 서비스 품질을 정량적으로 관리하는 방법론이다. “감으로 운영하는 시대”에서 “숫자로 ...
마이크로서비스 환경에서 하나의 요청이 수십 개 서비스를 거칠 때, 어디서 지연이 발생했는지 추적하는 기술이 분산 트레이싱이다.
Java로 Spring Boot를 쓰던 개발자가 Kotlin으로 전환할 때 가장 먼저 드는 생각은 “과연 다를 게 있나?” 이다. 결론부터 말하면, 다르다. 코드 줄 수가 줄고, null 안전성이 언어 수준에서...
시니어 개발자가 처음 Kafka를 쓸 때는 “토픽에 넣고, 토픽에서 꺼낸다”로 시작합니다. 그런데 6개월이 지나면 질문이 달라집니다. “주문 완료 시 네 개 토픽에 동시에 넣어야 하는데, 하나가 실패하면 어떻게...
한 줄 요약
한 줄 요약
한 줄 요약
한 줄 요약
계좌 이체 도중 잔액을 조회하면 어떤 값이 보여야 하는가? 격리 수준이 낮으면 존재하지 않는 돈을 보거나, 방금 있던 돈이 사라지거나, 없던 행이 유령처럼 나타난다. 이 글은 ACID의 내부 보장 메커니즘부터 ...
AWS는 200개가 넘는 서비스를 제공한다. 처음 마주하면 지도 없이 미로에 들어선 기분이다. 이 글은 백엔드 개발자가 실무에서 반드시 마주치는 핵심 서비스를 레이어별로 정리하고, 각 서비스가 왜 필요한지, 어...
GitOps는 Git 저장소를 인프라와 애플리케이션의 단일 진실 공급원(Single Source of Truth)으로 삼아, 클러스터 상태를 선언적으로 관리하는 운영 모델이다. ArgoCD는 이 GitOps 원...
GitHub Actions는 Workflow, Job, Step의 3계층 구조로 구성된 이벤트 기반 자동화 엔진이다. 단순한 CI/CD 도구를 넘어, Matrix Strategy로 수십 개 조합을 병렬 테스트하...
멀티 레이어 캐싱은 응답 속도가 다른 여러 계층의 캐시를 겹겹이 쌓아, 가장 빠른 계층에서 최대한 많은 요청을 소화하고 느린 계층으로는 최소한의 요청만 내려보내는 아키텍처다. 잘 설계된 멀티 레이어 캐시는 10...
컴퓨터 과학에는 유명한 농담이 있다. Phil Karlton의 말이다.
ChatGPT에게 “우리 회사 API 문서를 설명해줘”라고 물으면 모른다고 한다. 학습 데이터에 없기 때문이다. RAG(Retrieval-Augmented Generation)는 이 문제를 해결하는 현재 가장 ...
같은 GPT-4o에게 같은 질문을 해도 프롬프트에 따라 결과가 완전히 달라진다. “버그 고쳐줘”와 “당신은 시니어 Java 개발자입니다. 다음 NullPointerException의 근본 원인을 분석하고 방어 ...
ChatGPT 같은 서비스를 직접 만든다면 무엇이 필요할까. LLM API를 호출하는 것은 단 5줄이지만, 실제 프로덕션 서비스는 전혀 다른 이야기다. 토큰 비용 폭발, 프롬프트 인젝션 공격, 10초가 넘는 응...
“테스트는 나중에 쓰면 되잖아요?” 맞다. 그런데 나중에 쓰는 테스트와 먼저 쓰는 테스트는 근본적으로 다르다. 코드를 먼저 짜면 테스트는 그 코드의 동작을 확인하는 도구가 된다. 테스트를 먼저 쓰면 테스트가 설...
트위터가 140자 제한이었던 시절, https://www.example.com/very/long/path?campaign=summer&source=newsletter&medium=email 같은 ...
구글에 “파이썬 머신러닝”을 검색하면 수천억 개의 웹페이지 중에서 관련 결과가 100ms 안에 나온다. 단순히 “파이썬”과 “머신러닝”이 들어간 페이지를 하나씩 뒤지면? 전 세계 서버를 동원해도 수십 년이 걸린...
2023년 새벽 3시, 한 스타트업의 API가 다운됐다. 경쟁사 봇이 초당 5만 건을 보냈고, DB 커넥션 풀이 고갈되며 서비스 전체가 멈췄다. Rate Limiter가 있었다면 IP당 초당 100건 제한으로 ...
블랙프라이데이 자정, 쿠팡이 1억 명에게 동시에 “특가 시작!” 푸시를 보낸다. 10초 안에 전달되어야 한다. 단일 서버가 APNs와 FCM을 1억 번 직접 호출하면 서버는 즉시 죽는다. 알림 하나를 보내는 것...
BTS가 인스타그램에 사진을 올리는 순간, 7000만 팔로워의 피드가 업데이트되어야 한다. 7000만 건의 캐시 업데이트를 동기로 처리하면? 게시글 저장에 수십 분이 걸린다. 반대로 아무것도 하지 않으면? 팔로...
한 줄 요약: 시스템 디자인 면접의 핵심은 컴포넌트 나열이 아니라 “왜 이 선택인가”를 요구사항에서 논리적으로 도출하는 것이다. 암기가 아니라 사고 과정을 보여줘야 시니어 면접관을 설득할 수 있다.
한 줄 요약: 채팅 시스템은 WebSocket으로 양방향 실시간 연결을 유지하고, Kafka로 서버 간 메시지를 라우팅하며, Cassandra로 수 페타바이트 메시지를 저장한다. 각 선택에는 “왜 이것이어...
1. 비유 — 레고 블록과 조립 설명서
한 줄 요약: Spring Security는 서블릿 필터 체인 위에 구축된 보안 프레임워크다. 인증(Authentication)과 인가(Authorization)를 필터 파이프라인으로 처리하며, OAuth...
한 줄 요약: Spring MVC는 DispatcherServlet이 단일 진입점으로 모든 HTTP 요청을 받아 HandlerMapping → HandlerAdapter → ArgumentResolver ...
한 줄 요약: Spring Interceptor는 DispatcherServlet이 HandlerMapping으로 컨트롤러를 찾은 직후, 실제 호출 직전에 끼어드는 컴포넌트다. Filter와 달리 Spri...
1. 비유 — 요리 도구의 진화
한 줄 요약: Spring JDBC는 Driver→Connection→Statement→ResultSet이라는 JDBC 4단계 프로토콜을 JdbcTemplate 템플릿 메서드 패턴으로 감싸고, DataSo...
한 줄 요약: Spring IoC 컨테이너는 BeanDefinition 메타데이터를 읽어 싱글톤 레지스트리를 구성하고, BeanPostProcessor 체인으로 AOP 프록시를 씌운 뒤, 완성된 객체를 주...
한 줄 요약: Spring 컨테이너는 단순한 빈 저장소가 아니다. BeanPostProcessor 체인이 @Autowired·AOP 프록시·@Async를 자동화하고, BeanFactoryPostProces...
한 줄 요약: Spring Boot 자동 구성은 SpringApplication.run() 한 줄에서 출발해 classpath 분석, @Conditional 평가, 조건부 빈 등록까지 수백 개의 자동 설정...
사용자 프로필 페이지를 만든다고 하자. MySQL이라면 users, addresses, hobbies, orders 테이블을 JOIN해야 한다. MongoDB라면 쿼리 한 번으로 끝난다. 그런데 MySQL 개발...
서버에 동시 요청이 10만 개 들어온다. 전통적인 스레드 모델로는 스레드 10만 개가 필요하고, 각 스레드가 1MB를 쓴다면 메모리만 100GB다. 실제 서버가 가진 CPU 코어는 8개뿐인데. 코루틴은 스레드 ...
Java 프로젝트에서 NPE(NullPointerException)가 전체 런타임 에러의 40% 이상을 차지한다는 통계가 있다. Tony Hoare는 null을 설계한 것을 “10억 달러짜리 실수”라고 불렀다....
한 줄 요약: JVM은 바이트코드를 받아 검증·링킹·초기화 후 메모리에 올리고, 인터프리터와 JIT 컴파일러로 실행하며, GC로 메모리를 자동 회수하는 플랫폼 독립 런타임이다.
한 줄 요약: Java는 버전마다 “개발자가 반복적으로 겪는 고통”을 제거해왔다. 각 기능이 왜 만들어졌는지 이해하면 버전 변화가 하나의 흐름으로 보인다.
한 줄 요약: JIT(Just-In-Time) 컴파일러는 JVM이 바이트코드를 실행하면서 “자주 실행되는 코드”를 감지해 실시간으로 네이티브 기계어로 변환·최적화하는 엔진이며, 이것이 Java가 인터프리터...
“이 상태를 어디에 두어야 할까”라는 질문
막히는 도로를 뚫는 방법
클래스 없이 상태와 생명주기를 다루다
“전체를 다시 그리지 않는다”는 아이디어
음식점 준비 방식으로 이해하기
Express로 충분하지 않은 이유
아파트 입주 이야기
맥락에 따라 달라지는 “나”
가족 레시피 전수
식당 주방에서 일어나는 일
배달 음식의 비밀 봉투
음식 배달 앱의 진화
자동차 출고 검사처럼
도시를 처음부터 다시 지을 수는 없다
레스토랑 주방에서 음식이 나오기까지
블랙프라이데이 오전 9시, 트래픽이 갑자기 10배로 폭증했다. HPA가 Pod를 50개에서 500개로 늘리라는 신호를 보냈다. 그런데 새 Pod들이 실제로 트래픽을 받을 준비가 되는 데 5분이 걸렸다. 그 5분...
한 줄 요약
실생활 비유: 백화점 vs 전문점 거리
실생활 비유: 해외 송금과 공중 증발하는 돈
1. 비유 — 핵심 엔진과 외장 부품
API를 운영하다 보면 한 클라이언트가 초당 수천 건의 요청을 보내 서버 전체가 다운되거나, 브루트포스 공격으로 로그인 API가 마비되는 상황을 맞닥뜨린다. Rate Limiting은 이를 막는 첫 번째 방어선...
Tomcat 스레드 200개가 모두 외부 API 응답을 기다리며 블로킹되어 있다. 새 요청은 큐에서 대기하다 타임아웃이 터진다. 서버를 두 배 늘려도 스레드 수가 두 배가 될 뿐, 근본 구조는 바뀌지 않는다. ...
트랜잭션을 “그냥 @Transactional 붙이면 되는 것”으로 아는 개발자와, 프록시 체인부터 커넥션 풀 상호작용까지 이해하는 개발자의 차이는 장애 상황에서 극명하게 드러난다. 이 글은 Spring 트랜잭션...
JWT 없는 요청이 /api/admin을 통과했다. 필터가 누락됐는지, 순서가 잘못됐는지, SecurityContext가 비어있는지 — Spring Security 아키텍처를 모르면 어디서 막혀야 하는지조차 알...
마이크로서비스 환경에서 외부 서비스 호출은 반드시 실패한다. 문제는 “언제 실패하느냐”가 아니라 “실패가 얼마나 멀리 전파되느냐”이다. 하나의 느린 서비스가 연쇄적으로 전체 시스템을 마비시키는 Cascading...
새벽 2시에 운영 장애가 났다. 로그를 보니 에러와 정상 로그가 뒤섞여 어느 요청에서 터진 건지 찾을 수가 없다. MDC를 몰랐다면 이 상황에서 로그 전체를 시간순으로 읽어내려가야 한다.
신입 때 new RateDiscountPolicy()를 서비스 클래스 내부에 직접 박아뒀다가, 기획 변경 한 번에 수십 개 파일을 열어야 했던 경험이 있을 것이다. IoC와 DI는 그 고통을 제거하기 위한 개념...
마이크로서비스 환경에서 서비스들은 동적으로 생성·삭제·이동된다. IP와 포트를 하드코딩하면 배포할 때마다 설정을 바꿔야 한다. Spring Cloud Eureka는 이 문제를 해결하는 Service Discov...
100개의 마이크로서비스에 DB 비밀번호를 바꿔야 한다면? 각 서비스마다 설정 파일을 수정하고 재배포하면 수십 분이 걸린다. Spring Cloud Config는 모든 서비스의 설정을 한 곳에서 관리하고, 재배...
Spring Cloud Gateway는 Spring 생태계의 API Gateway 솔루션이다. Netflix Zuul(블로킹)의 후계자로, Spring WebFlux(Reactor/Netty) 기반의 비동기 논...
Spring @Async는 메서드 한 줄로 비동기를 선언할 수 있어 단순해 보인다. 하지만 내부 구조를 모르면 예외가 조용히 사라지고, 로그에서 TraceId가 증발하며, 트랜잭션 데이터가 보이지 않는 운영 장...
AOP를 “로깅이나 트랜잭션에 쓰는 것”으로만 알고 있다면 시니어 면접에서 멈춘다. 면접관이 진짜 묻는 것은 “프록시가 어떻게 만들어지는가”, “왜 self-invocation이 뚫리는가”, “CGLIB이 JD...
비유로 먼저 이해하기: HTTP 클라이언트 라이브러리를 택배사에 비유하면, RestTemplate은 직접 전화해서 배차하는 방식, WebClient는 배차 앱에 요청 올려두고 다른 일 하는 방식, Open...
동시 접속자가 늘어나는 순간, Tomcat과 Netty는 전혀 다른 방식으로 반응한다. 같은 Java 생태계, 같은 HTTP, 같은 서버이지만 설계 철학이 근본적으로 다르다. 그 차이가 10만 동시 접속에서 생...
동기(Synchronous), 비동기(Asynchronous), 블로킹(Blocking), 논블로킹(Non-blocking)은 I/O와 동시성 프로그래밍에서 가장 자주 혼용되는 개념이다. 단순히 “블로킹은 스레...
웹 서버가 수만 개의 동시 접속을 처리하는 방법에는 두 가지 철학이 있다. 하나는 “요청마다 사람을 붙인다”는 방식이고, 다른 하나는 “한 사람이 여러 일을 번갈아 처리한다”는 방식이다. Nginx는 후자를 극...
로그인 세션이 24시간 뒤 자동 만료되지 않는다면 어떻게 될까? 사용자가 로그아웃을 잊으면 세션은 영원히 메모리에 남는다. 수백만 명의 서비스라면 Redis 메모리가 조용히, 그러나 확실히 고갈된다. 어느 날 ...
새벽 2시, Redis 마스터 서버의 디스크가 고장났다. 복제 없이 단일 Redis만 운영 중이었다면? 캐시 데이터는 전부 날아간다. 서비스가 재개되어도 모든 캐시가 비어있으니 DB에 쿼리가 폭발적으로 몰린다....
채팅 서비스를 서버 3대로 운영한다. 사용자 A는 서버 1에 WebSocket으로 연결되어 있고, 사용자 B는 서버 2에 연결되어 있다. A가 B에게 메시지를 보낸다. 서버 1은 서버 2에 연결된 B에게 직접 ...
재고 감소 로직을 떠올려보자. GET으로 재고를 읽고, 0보다 크면 DECR로 줄인다. 코드로만 보면 아무 문제가 없다. 그런데 GET과 DECR 사이 0.05밀리초의 틈에 다른 스레드가 끼어들면 재고가 -1이...
쿠팡 블랙프라이데이 자정, 한정판 운동화 1켤레에 5만 명이 동시에 달려든다. 서버 20대가 저마다 “재고 1개 남음”을 읽고 결제를 진행하면, 재고는 1개인데 20명에게 팔리는 참사가 벌어진다. synchro...
실시간 랭킹을 구현해야 한다. MySQL로 매 요청마다 ORDER BY score DESC를 돌리면 수천 명이 동시 접속할 때 DB가 버티지 못한다. Redis Sorted Set 하나로 수백만 명의 점수를 실...
OSI 7계층을 “7·6·5·4·3·2·1 암기”로 끝내는 면접자와 “각 계층이 왜 존재하고 무엇을 해결하는가”를 설명하는 면접자는 결과가 다르다. 이 글은 후자를 위해 물리 신호 인코딩부터 HTTP/3 QUI...
트래픽이 폭발하는 순간, 서버는 두 가지 방식으로 죽는다. 느리게 죽거나, 갑자기 죽거나. 로드밸런서는 이 죽음을 막는 첫 번째 방어선이다. 단순히 요청을 나눠주는 장치가 아니라 장애 격리, SSL 오프로드, ...
DNS(Domain Name System)는 사람이 읽을 수 있는 도메인 이름(www.example.com)을 컴퓨터가 사용하는 IP 주소(93.184.216.34)로 변환하는 분산 계층 데이터베이스 시스템이다.
모니터링 시스템은 소프트웨어의 조종석이다. 시스템이 얼마나 잘 동작하고 있는지 측정하고(Metrics), 무슨 일이 일어났는지 기록하며(Logs), 요청이 어디를 거쳤는지 추적한다(Traces).
브로커 한 대가 새벽 3시에 갑자기 죽었다. 그 브로커가 리더를 맡던 파티션의 메시지는 어떻게 되는가? Kafka는 처음부터 이 질문에 답하기 위해 설계됐다. 단순히 “복제한다”가 아니라, 어떤 복제본이 신뢰할...
kafkaTemplate.send("orders", event) 한 줄이면 메시지가 전송된다고 생각하기 쉽다. 하지만 이 한 줄 뒤에는 인터셉터 → 직렬화 → 파티셔닝 → RecordAccumulator 배치 ...
주문이 DB에 저장됐는데 Kafka 발행이 실패했다. 결제 서비스는 주문을 모른다. 반대로 Kafka는 이벤트를 받았는데 DB가 롤백됐다. 결제 서비스는 존재하지 않는 주문을 처리한다. 이 두 가지 공포 시나리...
초당 100만 건의 이벤트를 처리하는 Kafka가 단순한 메시지 큐와 근본적으로 다른 이유는 하나다. OS와 하드웨어의 특성을 정확히 이해하고 그것을 최대한 활용하도록 설계됐기 때문이다. JVM 힙 대신 Pag...
서비스가 성장하면서 주문, 결제, 배달, 통계, 알림 시스템이 서로 직접 API를 호출한다. 하나가 느려지면 전체가 느려지고, 하나가 죽으면 연쇄 장애가 난다. Kafka는 이 결합을 끊는다. 그런데 “어떻게”...
들어가며
주문 이벤트 처리 속도가 발행 속도를 따라가지 못한다. 컨슈머 인스턴스를 한 대 더 띄우면 해결될까? 파티션이 3개인데 컨슈머가 이미 3개라면 4번째 컨슈머는 아무것도 하지 않고 대기만 한다. 더 심각한 문제는...
초당 수백만 메시지를 처리하는 Kafka 브로커는 어떤 내부 구조로 동작하는가? 단순히 “빠르다”는 사실이 아니라, SocketServer의 Acceptor/Processor 분리부터 Purgatory의 Tim...
개발 환경에서 멀쩡하던 API가 운영 트래픽에서 수백 ms 이상 걸린다면, 열에 아홉은 N+1 문제다. 단순히 JOIN FETCH를 쓰면 된다는 레시피는 누구나 안다. 하지만 면접관이 진짜 묻는 것은 왜 Hib...
Spring Boot 프로젝트에서 JPA를 쓴다고 해서 JPA를 안다고 할 수 없다. JpaRepository를 상속하고 findById를 호출하는 것은 시작일 뿐이다. N+1 쿼리가 왜 터지는지, merge(...
Java는 기본형(primitive type)과 참조형(reference type)이라는 두 가지 타입 체계를 가집니다. 이 둘 사이의 간극을 메우는 것이 래퍼 클래스(Wrapper Class)이며, 오토박싱(...
비유로 먼저 이해하기: 고속도로 톨게이트를 떠올려 보세요. 플랫폼 스레드는 차량 한 대가 통과할 때 톨게이트 직원 한 명을 완전히 점유합니다. 차가 카드를 찾는 동안(I/O 대기)에도 직원은 옆 차를 볼 ...
Java의 멀티스레드 환경에서 스레드 간 공유 없이 각 스레드마다 독립적인 변수를 유지해야 할 때 ThreadLocal을 사용합니다. 이 글에서는 ThreadLocal의 내부 구조부터 메모리 누수 방지, 실무 ...
주문 처리와 이메일 발송을 순차적으로 하면 사용자는 이메일 발송이 끝날 때까지 기다려야 한다. 스레드를 분리하면 주문 처리 응답을 즉시 돌려주고 이메일은 백그라운드에서 보낼 수 있다. 하지만 스레드를 잘못 다루...
Java에서 String은 가장 많이 사용되는 클래스이면서, 동시에 가장 많은 오해가 있는 클래스입니다. 불변성(Immutability), String Pool, 성능 최적화, 그리고 Java 11~17에서 추...
Java 8에서 등장한 Stream API는 단순히 for-loop를 대체하는 편의 문법이 아닙니다. 지연 평가(lazy evaluation), Spliterator 기반 분할, ForkJoin 병렬화, Col...
리플렉션은 런타임에 클래스 구조를 분석하고 동적으로 조작하는 강력한 기법입니다. Spring, JPA, Jackson, JUnit이 모두 이를 기반으로 동작합니다. 원리부터 실무 활용까지 상세히 정리합니다.
Java의 모든 클래스는 명시적으로 상속을 선언하지 않아도 java.lang.Object를 최상위 부모로 가집니다. Object 클래스가 제공하는 메서드들은 Java 객체 시스템의 근간을 이루며, 이를 올바르게...
Java는 소켓부터 HTTP 클라이언트까지 풍부한 네트워크 API를 제공합니다. TCP/UDP 저수준 통신부터 NIO 기반 고성능 서버까지 전체를 상세히 정리합니다.
Java는 클래스 안에 클래스를 선언할 수 있습니다. 이를 중첩 클래스(Nested Class)라고 하며, 종류에 따라 동작 방식과 사용 목적이 크게 다릅니다. 잘못 사용하면 메모리 누수의 원인이 되기도 하므로...
Java 8이 람다를 도입한 것은 단순한 문법 편의가 아닙니다. JVM 명령어 체계 자체를 확장(invokedynamic)하고, 런타임 코드 생성 메커니즘(LambdaMetafactory)을 추가하며, 함수형 ...
Java I/O는 단순한 파일 읽기/쓰기가 아닙니다. OS 커널의 시스템 콜, 페이지 캐시, epoll, zero-copy 같은 저수준 메커니즘이 Java API 뒤에 숨어 있습니다. 이 글은 “왜 그렇게 설계...
Java 제네릭은 1995년 출시된 Java에 2004년(Java 5) 뒤늦게 합류한 기능입니다. 단순한 “타입 파라미터 문법” 수준을 넘어, 타입 소거(Type Erasure), 브리지 메서드, PECS, 힙...
API 응답이 평소엔 8ms인데 가끔 340ms로 폭등한다. GC 로그를 열면 그 순간 Pause Full (Ergonomics) 312ms가 찍혀 있다. 원인은 알겠는데, 왜 이 시점에 Full GC가 터졌고...
Java는 본래 순수 객체지향 언어지만, Java 8부터 람다와 Stream API를 통해 함수형 프로그래밍 패러다임을 적극 수용했습니다. 함수형 프로그래밍의 핵심 개념을 이해하고 Java에서 어떻게 적용하는지...
Java의 예외 처리는 단순한 try-catch 문법을 넘어, 시스템의 견고성과 유지보수성을 결정하는 설계 영역입니다. 예외 계층 구조부터 커스텀 예외 설계, Spring의 예외 전략까지 완전히 정리합니다.
Java의 enum은 단순히 상수 집합을 표현하는 것을 넘어, 필드·메서드·추상 메서드를 가질 수 있는 완전한 클래스입니다. 상수 대신 Enum을 사용해야 하는 이유부터 EnumSet, EnumMap, 싱글톤 ...
Java 8에서 도입된 java.time 패키지는 기존 Date와 Calendar의 고질적인 문제를 해결하고, 불변(Immutable) 설계와 직관적인 API를 제공합니다. 현대 Java 개발에서 날짜·시간 처...
전자상거래 주문 처리 서버가 있다. 상품 정보(300ms), 재고 확인(200ms), 가격 계산(150ms)을 순차 호출하면 650ms다. 세 호출을 병렬로 띄우면 300ms면 충분하다. 그런데 단순히 Thre...
ArrayList와 LinkedList 중 무엇을 고를지, HashMap이 왜 멀티스레드에서 무한루프를 일으키는지, ConcurrentHashMap이 어떻게 락 없이 읽기를 처리하는지 — 이 질문들에 정확히 답...
한 줄 요약: JavaScript의 핵심은 싱글 스레드이면서도 비동기 처리가 가능한 이벤트 루프 메커니즘과, 렉시컬 스코프를 기억하는 클로저, 그리고 프로토타입 기반 상속입니다.
단일 MySQL 서버가 쓰기 TPS 한계에 부딪혔다. 읽기는 레플리카로 분산했지만 INSERT/UPDATE는 여전히 Primary 한 대가 감당한다. 수직 확장(더 좋은 서버)은 이미 96코어 / 384GB R...
비유로 시작하기
인덱스를 분명히 걸었는데 EXPLAIN을 보니 Full Table Scan이다. 옵티마이저가 인덱스보다 풀스캔이 더 빠르다고 판단한 것이다. 왜 그런 선택을 했는지 이해하지 못하면 힌트를 줄 수도, 통계를 갱신...
비유로 시작하기
비유로 시작하기
재고 1개짜리 상품에 10만 명이 동시에 주문을 쏟아냈다. 락 설계가 잘못되면 재고는 음수가 되고, 너무 강하면 시스템은 멈춰버린다. 락은 정합성과 성능 사이의 균형이다. 이 글에서는 InnoDB가 내부적으로 ...
프로덕션 장애 상황을 상상해 보자. 트래픽이 평소와 같은데 특정 쿼리의 p99 레이턴시가 갑자기 500ms에서 5초로 튀었다. 코드는 배포된 것이 없다. DBA를 불러 SHOW ENGINE INNODB STAT...
회원 테이블 1,000만 건에서 이메일 하나를 조회하는 데 5초가 걸렸다. 인덱스 하나를 추가했더니 3ms로 줄었다. 왜 이런 일이 벌어지는지, 단순히 “인덱스를 걸면 빠르다”는 수준을 넘어 B+Tree 내부 ...
“커넥션 풀 쓰면 빠르죠.” — 이 한 줄은 면접에서 0점이다. 왜 커넥션 하나를 여는 데 10ms가 걸리는지, HikariCP가 내부에서 어떤 자료구조로 락 없이 커넥션을 건네는지, 풀 사이즈를 왜 스레드 수...
비유로 먼저 이해하기: 데이터베이스를 식당에 비유하면, MySQL은 빠르고 친숙한 패스트푸드점, PostgreSQL은 다양한 메뉴와 재료를 갖춘 파인다이닝, Oracle은 규모와 신뢰성을 갖춘 대형 호텔 ...
Kubernetes(K8s)는 컨테이너 오케스트레이션 플랫폼이다. 수백 개의 컨테이너를 자동으로 배포, 스케일링, 복구한다. 개발자가 “3개의 인스턴스를 실행해”라고 선언하면, K8s는 그 상태를 항상 유지하려...
Docker는 소프트웨어를 컨테이너라는 표준 단위로 포장하는 기술이다. “내 로컬에서는 되는데 서버에서 안 돼요” 문제를 근본적으로 해결한다. 애플리케이션과 그 실행에 필요한 모든 것(라이브러리, 설정, 런타임...
CI/CD는 소프트웨어 개발의 컨베이어벨트다. 코드 변경이 자동으로 빌드 → 테스트 → 배포되며, 각 단계에서 품질이 검증된다. 수동 배포 과정에서 발생하는 휴먼 에러를 제거하고, 배포 주기를 단축한다.
로컬 캐시란? — 메모리 계층과 속도의 본질
캐싱은 자주 사용되는 데이터를 빠른 저장소에 보관해 응답 속도를 높이고 원본 데이터 소스의 부하를 줄이는 기법이다. 이 글은 단순한 개념 소개를 넘어, 각 전략이 왜 그 방식으로 동작해야 하는지, 잘못 쓰면 무...
왜 이게 중요한가?
한 줄 요약: 이벤트 기반 아키텍처(EDA)는 서비스들이 이벤트를 통해 간접 소통하여 결합도를 낮추고, 장애 전파를 차단하며, 시스템 확장성을 극대화하는 아키텍처 패턴이다.
한 줄 요약: DDD는 “코드가 비즈니스를 번역하는 것”이 아니라 “코드 자체가 비즈니스 언어로 말하는 것”을 목표로 한다. 모든 전술 패턴은 이 철학에서 필연적으로 도출된다.
AI 생태계는 2023년 이후 폭발적으로 성장했다. 개발자 워크플로우에 통합되는 코딩 어시스턴트부터 범용 챗봇, 이미지 생성, 인프라 레이어까지 각 영역별 주요 도구를 정리한다.
AI가 코드를 생성하는 시대가 되면서 개발자의 역할이 바뀌고 있다. AI를 단순히 사용하는 것을 넘어, AI가 올바르게 작동하도록 환경과 제약을 설계하는 하네스 엔지니어링(Harness Engineering)이...