본문 바로가기

전체 글76

saveAll() 썼다가 서버가 뻗었다고요? JPA 벌크 인서트(Bulk Insert)의 배신과 JdbcTemplate 100배 최적화 안녕하세요, 여러분의 든든한 IT 길잡이 데브프리입니다. 백엔드 실무를 하다 보면 외부 API에서 대량의 데이터를 긁어오거나, 운영팀이 넘겨준 수만 건의 엑셀(Excel) 데이터를 DB에 한 번에 밀어 넣어야 하는 상황(데이터 마이그레이션, 로그 적재 등)이 반드시 찾아옵니다. 스프링 부트(Spring Boot) 개발자라면 당연히 리스트에 데이터를 차곡차곡 담은 뒤, userRepository.saveAll(users)를 호출하며 쿨하게 퇴근을 준비할 것입니다. 하지만 실서버에서 이 코드가 실행되는 순간, 서버 CPU가 미친 듯이 치솟고 30초가 지나도 응답이 오지 않는 기현상을 마주하게 됩니다. 데이터가 10만 건을 넘어간다면 무시무시한 OutOfMemoryError와 함께 서버가 그대로 기절해 버리죠.. 2026. 8. 10.
배포만 하면 502 에러가 뜬다고요? 스프링 부트 무중단 배포의 완성, Graceful Shutdown 완벽 가이드 안녕하세요, 여러분의 든든한 IT 길잡이 데브프리입니다. 개발 서버에서는 완벽했던 코드를 실서버에 배포(Deploy)하는 순간은 늘 긴장됩니다. 특히 CI/CD 파이프라인을 통해 '무중단 배포(Zero-Downtime Deployment)' 환경을 구축해 두었다면, 사용자는 배포가 일어나는지조차 모르게 자연스럽게 새 버전으로 넘어가야 정상이죠. 하지만 실무에서는 새 버전을 배포하는 딱 그 1~2초 사이, 게시글을 등록하거나 결제를 진행하던 일부 사용자들에게 '502 Bad Gateway'나 'Connection Reset' 에러가 튀어나오는 아찔한 장애가 매우 빈번하게 발생합니다. "로드밸런서(LB)도 붙여놨고, 무중단 배포 툴도 썼는데 도대체 왜 트래픽이 유실되는 걸까요?" 이 현상의 핵심 원인은 기존.. 2026. 8. 9.
DB 부하를 줄이는 마법? 레플리케이션(Replication) 읽기/쓰기 분리와 복제 지연(Lag) 트러블슈팅 안녕하세요, 여러분의 든든한 IT 길잡이 데브프리입니다. 서비스가 성장하고 사용자가 늘어나면 가장 먼저 비명을 지르는 곳은 어디일까요? 바로 데이터베이스(DB)입니다. 웹 서버(WAS)는 트래픽이 몰리면 단순히 서버를 여러 대 띄워서(Scale-out) 로드밸런서로 묶어버리면 그만입니다. 하지만 모든 데이터가 최종적으로 저장되는 DB는 함부로 여러 대를 띄울 수 없습니다. 데이터의 일관성이 깨지기 때문이죠. 이때 백엔드 아키텍처에서 DB의 CPU가 100%를 치는 것을 막기 위해 가장 먼저 도입하는 실무 표준 기술이 바로 데이터베이스 레플리케이션(Replication)과 읽기/쓰기 분리(Read/Write Splitting)입니다. 하지만 이 기술을 스프링 부트(Spring Boot)에 연동하고 실서버에.. 2026. 8. 8.
100만 건 조회 시 서버가 뻗는다면? 오프셋(Offset) 페이징의 한계와 Spring Boot 3 커서(Cursor) 기반 페이징 최적화 안녕하세요, 여러분의 든든한 IT 길잡이 데브프리입니다. 백엔드 개발자로 일하다 보면 서비스 런칭 초기에는 전혀 문제가 없다가, 데이터가 100만 건, 1,000만 건 단위로 쌓이기 시작하면서 갑자기 특정 API가 3~5초씩 걸리는 기현상을 마주하게 됩니다. APM(성능 모니터링) 툴을 열어보면 어김없이 '게시글 목록 조회', '주문 내역 조회' 같은 페이징(Pagination) 쿼리에서 붉은색 슬로우 쿼리(Slow Query) 경보가 울리고 있죠. "페이징 처리에 인덱스도 잘 태웠는데 도대체 왜 느려진 걸까요?" 이 현상은 우리가 무심코 사용하던 Spring Data JPA의 기본 Page 객체와 OFFSET 쿼리가 가진 치명적인 태생적 한계 때문입니다. 오늘은 대용량 트래픽과 데이터를 다루는 실무에서.. 2026. 8. 7.
회원가입 API가 5초나 걸린다고요? @TransactionalEventListener로 스파게티 코드 분리하기 안녕하세요, 여러분의 든든한 IT 길잡이 데브프리입니다. 백엔드 서버를 개발하다 보면 서비스 규모가 커질수록 하나의 API에 수많은 요구사항이 덕지덕지 붙기 시작합니다. 처음에는 단순히 DB에 회원 정보를 저장하기만 했던 '회원가입 API'가 있다고 가정해 봅시다.시간이 지나면서 기획팀의 요구에 따라 "가입 시 환영 이메일 발송", "가입 축하 1,000 포인트 지급", "슬랙(Slack) 알림 전송" 기능이 끝없이 추가됩니다. 이 모든 로직을 UserService.register()라는 하나의 메서드에 욱여넣으면 어떤 일이 발생할까요? 이메일 발송 서버가 느려지면 사용자는 회원가입 버튼을 누르고 5초 동안 멍하니 로딩 화면만 봐야 합니다. 더 최악인 것은, 이메일 발송에 실패해서 예외가 터지면 회원가입.. 2026. 8. 6.
API가 3초간 멈춘다고요? 스프링 부트 OSIV(Open Session In View)의 배신과 최적화 가이드 안녕하세요, 여러분의 든든한 IT 길잡이 데브프리입니다. 스프링 부트(Spring Boot)로 JPA 기반의 백엔드 프로젝트를 띄울 때마다, 콘솔 창에 노란색 경고(WARN) 로그가 거슬리게 찍히는 것을 본 적 있으신가요?PlaintextWARN 12345 --- [main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning초보 시절에는 이 경고를 대수롭.. 2026. 8. 5.