이론상 10만 QPS를 처리할 수 있는 티켓팅 시스템
유명인의 내한으로 이벤트를 열게 되었다. 선착순 1,000명에게만 주어지는 기회다. 티켓팅 신청을 웹 애플리케이션으로 받으려고 계획 중이며, 요구사항은 아래와 같다. 분산 락을 통해 락을 걸었다고 해보자. 혹시 완벽하게 동시성을 제어했다고 안심하고 있는가?
글 9편

유명인의 내한으로 이벤트를 열게 되었다. 선착순 1,000명에게만 주어지는 기회다. 티켓팅 신청을 웹 애플리케이션으로 받으려고 계획 중이며, 요구사항은 아래와 같다. 분산 락을 통해 락을 걸었다고 해보자. 혹시 완벽하게 동시성을 제어했다고 안심하고 있는가?

분산 락의 try-finally가 비즈니스 로직을 가릴 때, Spring AOP로 그 코드를 빼는 방법이다. @Transactional처럼 쓰는 DistributedLock과 SpEL로 락 키를 고르는 과정까지 담았다.

"Lettuce는 SpinLock만 지원한다"는 잘못된 정보를 바로잡는다. Spring RedisLockRegistry의 PubSub Lock 설정으로 Redisson 없이도 효율적인 분산 락을 구현하는 방법을 소개한다.

좋아요를 저장할 때의 동시성 문제를 비관적 락으로 푸는 과정이다. 락의 동작과, 없는 행 때문에 넥스트 키 락이 성능을 떨어뜨리는 지점까지 살펴본다.

synchronized의 JVM 모니터 락이 실제로 어떻게 동작하는지 보고, ReentrantLock으로 생산자-소비자 문제를 푼 뒤, 사용자별 키로 락을 나눠 성능을 높인다.

Network I/O가 스레드를 막던 문제를 JDK 21 가상 스레드로 풀었다. 도입 중에 나타난 Thread Pinning과 Overwhelming의 원인과, 각각을 넘긴 방법을 함께 정리했다.

선착순 이벤트 시스템을 설계한다고 가정해보자. 요구사항은 아래와 같다. 100개의 재고가 있을 때 동시에 1,000명이 요청하면 어떻게 정확히 100명에게만 제공할 수 있을까? 이때 일반적으로 제시되는 해결책들은 아래와 같다.

한 화면에 날짜별 배송 계획 40~60건을 외부 API로 불러와야 해서 응답이 느렸다. Redis 캐시와 로컬 캐시로 50~100배 빨라졌지만, 서버마다 어긋나는 로컬 캐시는 Redis Pub/Sub으로 맞췄다.

멀쩡해 보이던 시스템도 무심코 작성한 코드 한 줄 때문에 느려지고 결국 멈출 수 있다. 작은 메모리 관리 실수가 어떻게 장애로 번지는지 짚는다.