세마포어와 permit - 동시에 몇 개까지 들일지를 세는 도구, 그리고 벌크헤드 Notes 무너지는 Spring 서버 1편의 조치는 두 가지였다. 읽기 타임아웃 2초, 그리고 “벌크헤드 permit 20”이다. 업스트림 호출 안에 동시에 들어갈 수 있는 요청 스레드 수를 세마포어로 20개로 묶고, permit을 100ms 안에 못 얻으면 503으로 거절했다. 그 결과 thread dump에서 업스트림 읽기에 있는 스레드가 정확히 20개였다.... 2024/12/27 Java
thread dump 읽는 법 - 스레드 상태와 스택 프레임, 그리고 RUNNABLE이 CPU를 쓴다는 뜻이 아닌 이유 Notes 무너지는 Spring 서버 1편에서 업스트림 하나가 느려지자 그것을 호출하지도 않는 /api/fast가 죽었다. CPU 사용률은 낮았다. 지표만 보면 서버는 한가했다. 원인을 확정한 것은 thread dump였다. 요청 스레드 200개 전부가 sun.nio.ch.Net.poll에 멈춰 있었다. 이 글은 그 한 줄을 읽기 위해 필요한 것을 처음부터 정리... 2024/12/17 Java
모델 검사 입문 - TLA+, TLC, 상태 공간, 불변조건, 반례 Notes 이후 ParityPay 12편이 이런 상황에서 시작했다. 부하·장애 실험 41종과 통합 시험 328개를 돌렸는데도 “고객은 청구됐는데 결제는 실패로 확정된” 경로를 한 번도 밟지 못했다. 그 경로는 기관이 요청을 받았지만 아직 기록하지 않은 짧은 창 안에서 조회가 두 번 일어나야 드러난다. 시험은 그 순간이 오기를 기다릴 수밖에 없다. 반면 TLC는 ... 2024/12/07 Programming
Lock-Free와 CAS - 락 없이 공유 변수를 바꾸는 방법과 그 한계 Notes 카카오뱅크 알림 플랫폼 리뷰에 이런 문장이 나온다. 큐를 나누는 시점을 “CAS로 원자적으로 잡고”, 그 구현을 Lock-Free라고 부른다. Kleppmann 분산락 리뷰에서도 ZooKeeper znode 버전을 쓰기 조건에 넣으면 “CAS가 된다”고 적었다. 두 글 모두 CAS와 Lock-Free를 설명 없이 썼으므로, 이 글에서 처음부터 정리한다... 2024/11/28 Java
JPA 활용 2편 복습: API 응답과 조회 전략을 분리하기 Lecture 엔티티 조회와 DTO 조회를 구분하고 연관관계, 컬렉션 페치 조인, 페이징의 제약을 함께 정리한다. 2024/11/23 Spring
프로세스는 왜 멈추는가 - GC, 페이지 폴트, CPU 경합, SIGSTOP, VM 정지와 스스로 알 수 없는 멈춤 Notes Kleppmann의 분산락 글 리뷰는 이런 장면에서 시작한다. 클라이언트 1이 락을 쥐고 파일을 읽는다. 쓰기 직전에 프로세스가 잠깐 멈춘다. 그 사이 lease가 끝나고 클라이언트 2가 락을 쥐고 쓴다. 클라이언트 1이 깨어나 자기 lease가 끝난 줄 모르고 쓴다. 두 쓰기가 겹친다. 이 장면에서 낯선 것은 “프로세스가 멈춘다”는 부분이다. 코드... 2024/11/18 OS
읽기 수리, 쓰기 수리, 비동기 수리 - 최종 일관성은 누가 언제 맞추는가 Notes Airbnb 결제 멱등성 글 리뷰에는 이런 문장이 나온다. 2PC 없이 최종 일관성을 얻는 흔한 방법이 read repair, write repair, asynchronous repair 셋이고, Airbnb 결제는 셋을 다 쓰며, 그 글은 write repair를 다룬다. 세 단어가 한 문장에 묶여 나오지만 각각이 무엇을 고치는지는 설명이 없다. ... 2024/11/09 Database
사용자 공간과 커널 공간 - 시스템 콜, 복사, sendfile과 kTLS Notes 두 글에서 같은 경계가 등장한다. TLS 핸드셰이크의 비용은 사용자 공간 TLS 라이브러리로 암호화하면 데이터가 사용자 공간을 지나야 해서 sendfile()을 쓸 수 없고, kTLS가 예외라고 했다. NIO와 이벤트 루프는 힙 버퍼로 IO를 하면 JVM이 다이렉트 버퍼로 한 번 더 복사한다고 했다. 둘 다 “데이터가 어느 공간에 있는가”의 문제다. ... 2024/10/29 OS
TLS 키 교환과 암호 스위트 - key share, forward secrecy, PSK, AES-NI Notes TLS 핸드셰이크의 비용에는 몇 개의 용어가 설명 없이 나온다. TLS 1.3 클라이언트는 ClientHello에 “키 공유 추정값”을 미리 싣고, 1.3은 “정적 RSA 스위트를 제거”했고, 재개는 “PSK 교환”으로 바뀌었고, 대칭 암호는 “AES-NI 덕분에 거의 공짜”라고 했다. 이 글은 그 네 가지를 처음부터 설명한다. 두 단계로 나뉘는... 2024/10/19 Network
다이렉트 메모리와 Cleaner - 힙 밖의 버퍼는 누가 언제 해제하는가 Notes NIO와 이벤트 루프의 마지막 부분에 이런 경고를 적었다. Netty의 ByteBuf에서 release()를 잊으면 다이렉트 메모리가 새고, 이 누수는 힙 덤프에 안 보인다. 같은 글에서 다이렉트 버퍼는 Cleaner에 의존하므로 회수 시점이 불확실하다고도 했다. 카카오뱅크 알림 플랫폼 리뷰에서도 레거시가 OOM으로 이어졌고, 신규 구현은 고정 크기 ... 2024/10/08 Java