Framework (60) 썸네일형 리스트형 [Spring Boot] ELK 스택 (Elasticsearch, Logstash, Kibana): 중앙 집중형 로그 파이프라인 여러분이 성공적인 서비스를 만들어 서버가 50대로 늘어났습니다. 어느 날 밤, 고객센터에서 "결제가 자꾸 실패한다고 고객 클레임이 들어옵니다!"라는 다급한 연락이 옵니다. 초보 개발자는 리눅스(Linux) 터미널을 열고 1번 서버에 접속해 tail -f /var/log/spring.log를 치고 한참 찾다가 없으면 2번 서버에 들어가서 또 찾습니다. 50대의 서버를 일일이 돌아다니며 에러 로그를 찾는 사이에 고객은 다 떠나고 회사는 망할 것입니다. 수십 대의 서버에서 각자 뿜어내는 수 기가바이트(GB)의 텍스트 로그 파일들을 한 곳으로 빨아들여서, "결제 에러"라는 키워드 하나만 치면 구글처럼 0.1초 만에 50대 서버 전체의 에러 로그를 찾아주고 삐까뻔쩍한 대시보드로 시각화해 주는 인프라는 없을까요? .. [Spring Boot] Elasticsearch 연동: RDB의 LIKE 검색 한계를 부수다 여러분이 당근마켓 같은 중고 거래 플랫폼을 만들었다고 가정해 봅시다. 데이터베이스(MySQL)에 등록된 상품 제목이 1,000만 개입니다. 사용자가 검색창에 "시원한 여름용 원피스"라고 검색했습니다. 일반적인 자바 개발자는 무심코 SELECT * FROM product WHERE title LIKE '%시원한 여름용 원피스%'라는 쿼리를 날립니다. 이 쿼리(퍼지 검색)는 인덱스(Index, 색인)를 타지 못하고 1,000만 개의 테이블 전체를 처음부터 끝까지 하나하나 스캔(Full Table Scan)해야 하므로 결과가 나오기까지 5초~10초가 걸리며 DB CPU가 터져버립니다. 게다가 사용자가 "여름 원피스"라고 띄어쓰기를 조금만 다르게 해도 결과가 0건으로 안 나옵니다! 관계형 데이터베이스(RDB)는.. [Spring Boot] Spring Batch Chunk 지향 처리: 1,000만 건 메모리 최적화의 꽃 앞선 33단계에서 우리는 Spring Batch의 기본 뼈대인 Job과 Step을 배웠습니다. 하지만 실무에서 주어지는 '1,000만 명의 VIP 등급 업데이트' 같은 거대한 과제를 단일 Tasklet으로 처리하려 든다면, List users = userRepository.findAll()을 호출하는 순간 1,000만 개의 자바 객체가 메모리(RAM)에 올라가며 1초 만에 OOM(OutOfMemory) 에러와 함께 서버가 폭발하게 됩니다. 그렇다고 1건씩 DB에서 읽어와서 1건씩 UPDATE 쿼리를 날린다면? 1,000만 번의 네트워크 I/O(통신 비용)가 발생하여 배치가 끝나는 데 일주일이 넘게 걸릴 것입니다. 메모리를 터뜨리지 않으면서도 미친 듯이 빠른 속도를 내는, 이 두 마리 토끼를 잡기 위해 고.. [Spring Boot] Spring Batch 입문: 1,000만 건의 데이터를 씹어 삼키다 웹 서비스 백엔드 개발자들은 주로 사용자가 스마트폰에서 버튼을 누르면 0.1초 만에 응답(JSON)을 주는 '실시간(Real-time)' 처리에 익숙합니다. 그런데 실무에서는 이런 요구사항이 비일비재하게 떨어집니다. "매월 1일 자정마다, 전체 회원 1,000만 명의 지난 한 달 치 결제 내역을 싹 다 조회해서 합산한 뒤, 50만 원 이상 쓴 사람들의 등급을 VIP로 업데이트하고 쿠폰을 발급해 주세요." 이 작업을 일반적인 스프링 웹 컨트롤러 안에서 for문 1,000만 번을 돌려서 처리하면 어떻게 될까요? 99.9% 확률로 메모리 초과(OOM)로 서버가 죽거나, 중간에 DB 커넥션이 끊겨서 '500만 명까지만 처리되고 멈추는' 끔찍한 대참사가 벌어집니다. 500만 명을 다시 어떻게 롤백할까요? 상상만 .. [Spring Boot] STOMP와 RabbitMQ: 엔터프라이즈급 실시간 채팅의 완성 이전 31단계에서 우리는 순수 WebSocket을 사용해 양방향 통신을 뚫어보았지만, "단톡방 구분이 안 된다", "메시지 포맷이 중구난방이다", "서버가 여러 대면 통신이 끊긴다"는 치명적인 세 가지 장벽에 부딪혔습니다. 실무 카카오톡이나 디스코드 같은 대규모 실시간 서비스는 이 문제를 어떻게 해결할까요? 바로 웹소켓이라는 텅 빈 고속도로 위에, STOMP(Simple Text Oriented Messaging Protocol)라는 엄격한 교통 규칙(신호등과 차선)을 세우고, 여러 서버 간의 메시지 배달을 책임지는 RabbitMQ(메시지 브로커)라는 거대한 우체국을 도입하는 것입니다.이번 [Spring Boot 실무 완벽 가이드] 시리즈에서는 "실무 실시간 서비스 아키텍처의 절대 표준!" STOMP 프.. [Spring Boot] WebSocket 실시간 채팅: 양방향 통신의 서막 우리가 매일 사용하는 카카오톡이나 주식 거래 앱의 호가창은 어떻게 실시간으로 데이터가 번쩍번쩍 업데이트될까요? 초보 개발자들은 프론트엔드에서 setInterval() 함수를 써서 1초마다 백엔드에 "새로운 채팅 온 거 있어?"라고 묻는 폴링(Polling) 방식을 떠올립니다. 하지만 1,000명의 유저가 1초마다 빈 요청(HTTP)을 보내면 서버는 채팅을 하기도 전에 트래픽 폭탄을 맞고 터져버릴 것입니다. 웹의 근간인 HTTP는 본래 '단방향(클라이언트가 물어보면 서버가 대답하고 끊음)' 통신이기 때문입니다.이 HTTP의 태생적 한계를 부수고, "클라이언트와 서버가 한 번 손을 잡으면(Handshake) 연결을 끊지 않고, 서버가 원할 때 언제든 클라이언트에게 데이터를 쏴줄 수 있는 고속도로"를 뚫어주는.. [Spring Boot] GraalVM Native Image: 자바의 한계를 찢고 0.05초 만에 부팅하라 현대 클라우드 생태계는 요금이 저렴하고 유연한 AWS Lambda 같은 서버리스(Serverless)나 쿠버네티스(K8s) 오토스케일링 환경으로 빠르게 넘어가고 있습니다. 이런 환경에서는 트래픽이 몰릴 때 서버(컨테이너)가 1초 만에 수십 대씩 팟! 팟! 하고 순식간에 떠야 합니다. 그런데 여기서 자바(Java) 진영에 치명적인 위기가 찾아옵니다. 자바는 .jar를 실행하면 무겁고 거대한 JVM(자바 가상머신)을 먼저 띄운 뒤, 그 위에서 바이트코드를 통역(JIT)하며 스프링의 수많은 빈(Bean)들을 메모리에 올리느라 서버 부팅에만 최소 5초~15초가 걸립니다. Go나 Node.js가 0.1초 만에 켜지는 것에 비하면 너무나 뚱뚱하고 둔한 것이죠. "이제 클라우드 시대에 자바는 끝났다"는 조롱이 쏟아지.. [Spring Boot] Spring WebFlux: 한계 돌파, 비동기 논블로킹(Non-Blocking)의 기적 JMeter로 1만 명의 부하 테스트를 때리다 보면, 평범한 Spring MVC(톰캣 기반) 서버가 어느 순간 맥없이 무너지는 것을 보게 됩니다. 이유가 뭘까요? 기존 방식은 '1 요청 = 1 쓰레드(Thread)'라는 치명적인 룰을 가집니다. 유저가 API를 호출하면 쓰레드 하나가 배정되고, 그 쓰레드는 데이터베이스에서 쿼리 결과를 가져오는 2초 동안 '대기(Blocking)' 상태에 빠집니다. 아무 일도 안 하면서 쓰레드를 꽉 쥐고 있는 거죠. 이렇게 200명의 유저가 동시에 접속해 쓰레드 200개가 전부 DB 응답을 기다리며 멈춰버리면, 201번째 유저부터는 하얀 화면만 보며 에러를 뱉게 됩니다(Thread Pool 고갈). "아니, DB 기다리는 동안 쓰레드가 놀지 말고, 돌아가서 다른 유저 요청.. [Spring Boot] JMeter 부하 테스트: 트래픽 폭탄을 쏘고 병목을 부숴라 여러분이 만든 수강신청 시스템이 내일 아침 9시에 오픈합니다. 개발자 본인이 로컬 환경에서 포스트맨(Postman)으로 /api/enroll API를 한 번 클릭했을 때는 응답 속도가 0.1초(100ms)로 완벽했습니다. 하지만 다음 날 아침 9시, 1만 명의 학생이 동시에 접속(새로고침 연타)을 시작하자마자 서버는 "Connection Timeout"을 뱉으며 장렬히 전사했습니다. 1만 개의 트래픽이 쏟아질 때 DB 커넥션 풀(HikariCP)이 버티는지, CPU가 몇 퍼센트까지 치솟는지, 톰캣(Tomcat)의 기본 쓰레드 200개가 부족하진 않은지 미리 검증하지 않은 대가입니다. 오픈 당일 사직서를 쓰고 싶지 않다면, "실제 유저 1만 명이 접속하는 것과 똑같은 환경을 시뮬레이션해서 가짜 트래픽 폭탄.. [Spring Boot] 힙 덤프(Heap Dump) 분석: 메모리 누수(OOM)의 범인을 체포하라 자바(Java)의 가장 큰 장점 중 하나는 개발자가 메모리(RAM) 관리에 신경 쓰지 않아도 된다는 것입니다. 객체를 다 쓰고 나면 가비지 컬렉터(Garbage Collector, GC)라는 청소부가 돌아다니며 쓰레기를 싹 치워주기 때문이죠. 그런데 여러분이 만든 쇼핑몰 서버가 일주일만 지나면 서서히 메모리가 차오르더니 java.lang.OutOfMemoryError (OOM)을 뱉으며 장렬히 전사하는 현상이 발생했습니다. 청소부(GC)가 왜 쓰레기를 치우지 못했을까요? 개발자가 코드 어딘가에서 List나 Map 같은 저장소에 객체를 계속 쌓아두기만 하고 빼지 않으면(참조를 유지하면), GC는 "어? 이 객체는 아직 쓰고 있는 중요한 데이터인가 보네? 치우지 말아야지!" 하고 냅두게 됩니다. 이것이 바로.. [Spring Boot] Docker 컨테이너화: "내 로컬에선 되는데 서버에선 안돼요"를 끝내다 여러분이 윈도우(Windows) 노트북에서 Java 17을 설치하고 스프링 부트(Spring Boot) 서버를 완벽하게 개발했습니다. "완벽해! 이제 배포하자!"라며 리눅스(Linux) 운영 서버에 .jar 파일을 올리고 실행했는데, 갑자기 "Unsupported Class Version Error"가 뜨며 서버가 뻗어버립니다. 알고 보니 리눅스 서버에는 Java 11이 깔려있었던 것입니다. 부랴부랴 Java 17로 업데이트했더니 이번엔 파일 경로(Path) 문제로 이미지가 엑스박스가 뜹니다. 개발자의 로컬 환경, 테스트 서버 환경, 라이브 운영 서버 환경이 조금씩 달라서 생기는 이 지긋지긋한 '환경 불일치 문제'는 지난 수십 년간 수많은 개발자의 밤을 지새우게 만들었습니다. 이 고통을 완벽하게 끝내기 .. [Spring Boot] 무중단 배포 전략: Nginx와 블루/그린(Blue/Green) 아키텍처 새벽 3시, 개발자가 버그를 고치고 새로운 스프링 부트(Spring Boot) 버전(V2)을 배포(Deploy)하기 위해 서버에 접속합니다. 기존에 돌고 있던 V1 서버 프로세스를 kill 명령어로 죽이고, 새로운 V2 .jar 파일을 java -jar 명령어로 기동 시킵니다. 스프링의 거대한 프레임워크가 톰캣(Tomcat)을 띄우고 메모리에 빈(Bean)들을 올리는 데 약 10~15초가 소요됩니다. 문제는 이 15초 동안 사이트에 들어온 사용자들은 끔찍한 "502 Bad Gateway" 또는 "연결할 수 없음" 에러 페이지를 마주하게 된다는 것입니다. (다운타임 발생) 과거에는 고객들이 잠든 새벽에 서버를 내리고 작업(점검 시간)하는 것이 당연했지만, 24시간 글로벌로 돌아가는 현대의 서비스(넷플릭스,.. [Spring Boot] API 문서화의 끝판왕: Swagger(Springdoc)와 REST Docs의 대결 백엔드 개발자가 API 100개를 열심히 다 만들었습니다. 이제 이 API를 가져다 써야 하는 프론트엔드(React, iOS) 개발자와 핏대 높여 싸울 시간이 왔습니다. "회원가입 파라미터가 userName인가요 user_name인가요?", "에러가 났을 때 리턴되는 JSON 응답 양식 좀 엑셀로 정리해서 주세요!" 과거에는 노션(Notion)이나 엑셀에 한 땀 한 땀 API 스펙을 수동으로 적어주었습니다. 하지만 백엔드 코드가 수정될 때 문서 업데이트를 깜빡하는 순간, 코드는 최신인데 문서는 구버전인 '거짓말 문서'가 되어버리고 프론트엔드의 비난을 한 몸에 받게 됩니다. 이 끔찍한 비효율과 커뮤니케이션 비용을 제로(0)로 만들기 위해 등장한 구원자가 바로 "자바 코드를 읽어서 자동으로 멋진 웹페이지 A.. [Spring Boot] Apache Kafka 연동: MSA의 대동맥, 이벤트 주도 비동기 통신 배달 앱에서 고객이 치킨을 '결제'했다고 상상해 봅시다. 백엔드 시스템 내부에서는 어마어마한 일들이 순차적으로 벌어집니다. 1. 주문 시스템에 접수 -> 2. 라이더 배차 시스템 호출 -> 3. 고객에게 카카오톡 알림 발송 -> 4. 쿠폰 소진 처리. 만약 결제 서버가 이 4개의 서버에게 일일이 HTTP(REST API)로 전화를 걸어 "야, 결제됐어! 일해!"라고 동기식(Synchronous)으로 통신하면 어떻게 될까요? 만약 카카오톡 알림 서버가 장애로 3초간 멈춰있다면, 결제 서버도 그 3초 동안 응답을 기다리며 멈춰있게 되고 결국 사용자의 화면은 하얗게 굳어버립니다. 하나의 서버 장애가 전체 시스템의 장애로 퍼지는 '도미노 붕괴(강한 결합)' 현상입니다. 이 끔찍한 의존성을 칼같이 끊어내기 위해 .. [Spring Boot] Spring Cloud Config: 50개의 서버 설정을 단 한 곳에서 통제하라 회사가 거대해지면 하나의 거대한 스프링 부트(Spring Boot) 애플리케이션(Monolithic)은 한계를 맞이합니다. 결제팀은 결제 로직만, 회원팀은 회원 로직만 따로 떼어내어 각각 50개의 독립적인 서버로 쪼개는 마이크로서비스 아키텍처(MSA, Microservice Architecture)의 시대가 열립니다. 그런데 이 MSA 환경에서 인프라 엔지니어를 가장 고통스럽게 만드는 것은 코드가 아니라 다름 아닌 application.yml 설정 파일입니다. 공통으로 사용하는 'Redis 서버 IP'가 바뀌거나 '결제 연동 API Key'를 변경해야 할 때, 50개의 프로젝트 레포지토리를 열어서 일일이 yml을 수정하고, 50번의 도커(Docker) 이미지를 다시 굽고, 50대의 서버를 재시작해야 하는.. [Spring Boot] Actuator 모니터링: 서버의 심장 박동을 실시간으로 감시하라 열심히 개발한 스프링 부트(Spring Boot) 서버를 무사히 라이브(Live) 환경에 배포했습니다. 그런데 배포 후 3일째 되는 날, 유저 한 명이 "홈페이지가 엄청 느려요!"라고 게시판에 불평을 남겼습니다. 이 말을 들은 개발자는 등골이 오싹해집니다. "서버 메모리가 다 차서 느려진 건가? 아니면 DB 커넥션이 부족한가? 혹시 특정 API가 유독 늦게 응답하는 건가?" 원인을 찾기 위해 리눅스 서버에 SSH로 접속해서 top 명령어를 치거나, 끝도 없이 올라가는 로그 텍스트를 눈알이 빠지도록 쳐다보는 것은 원시 시대의 방식입니다. 서버 스스로가 자신의 건강 상태(Health), 메모리, CPU 사용량, DB 연결 상태, 최근 100개의 HTTP 요청 내역 등을 완벽한 JSON 데이터로 뱉어내 주면 .. [Spring Boot] 테스트 코드 작성법: JUnit 5와 Mockito로 버그 없는 불사신 서버 만들기 초보 개발자와 실무 프로 개발자를 가르는 가장 거대하고 뚜렷한 경계선은 바로 '테스트 코드(Test Code)'의 존재 여부입니다. 학원 프로젝트 시절에는 기능을 구현하고 서버를 켠 뒤, 포스트맨(Postman)으로 API를 한 번 호출해 보고 성공이 뜨면 "우와! 다 됐다!" 하고 환호하며 코딩을 끝냈습니다. 하지만 6개월 뒤, A 기능을 살짝 수정했는데 전혀 상관없어 보이던 B 기능과 C 기능이 연쇄적으로 펑펑 터지기 시작합니다. 어디서부터 손대야 할지 몰라 밤을 새우는 '레거시 코드의 늪'에 빠지게 되죠. 만약 수백 개의 기능이 "나는 지금 정상적으로 작동하고 있어!"라고 매번 자동 검증해 주는 시스템이 있었다면 어땠을까요? 코드가 코드를 검증하고, 내 로직이 100% 옳다는 것을 수학적으로 증명해.. [Spring Boot] 파일 업로드와 AWS S3 연동: 서버 디스크의 한계를 클라우드로 돌파하라 게시판에 사용자가 10MB짜리 고화질 사진을 첨부하여 글을 작성합니다. 초보 시절에는 MultipartFile 객체를 받아 스프링 부트(Spring Boot)가 구동되고 있는 로컬 서버의 C:\upload 디렉토리나 리눅스 /var/www/images 폴더에 file.transferTo() 코드로 저장(Save)하는 방식을 썼습니다. 서버가 딱 1대일 때는 이 방식이 기가 막히게 잘 돌아갑니다. 하지만 대박이 터져서 서버를 3대(A, B, C)로 스케일 아웃(Scale-out)하는 순간 지옥문이 열립니다. 사용자가 A서버에 접속해 프로필 사진을 올렸는데, 내일 다시 접속할 땐 로드밸런서가 B서버로 연결해 주면? B서버 디스크에는 사진이 없으므로 화면에 끔찍한 '엑스박스(이미지 깨짐)'가 뜹니다. 게다가 .. [Spring Boot] 비동기(@Async)와 스케줄링(@Scheduled): 무거운 작업을 뒤로 빼라 여러분이 야심 차게 런칭한 서비스의 회원가입 로직을 짜고 있습니다. 1. 유저 정보 DB 저장 -> 2. 포인트 지급 -> 3. 환영 이메일 발송 순서로 코드를 짰습니다. DB 저장은 0.1초면 끝나지만, 외부 메일 서버를 거치는 '이메일 발송'은 무려 3초가 걸립니다. 사용자가 [가입하기] 버튼을 누르면 이 모든 작업이 '직렬(동기)'로 실행되어 브라우저 화면이 3초 넘게 하얗게 멈춰있게 됩니다. 성질 급한 한국 유저들은 서버가 죽은 줄 알고 새로고침을 연타하다가 결국 이탈해 버릴 것입니다. 이럴 때 백엔드 개발자의 센스가 발휘되어야 합니다. "이메일 발송 같은 건 메인 응답에 영향을 주지 않도록 다른 쓰레드(알바생)에게 짬처리(?) 시키고, 나는 유저에게 0.1초 만에 '가입 성공!'을 외쳐주자!" .. [Spring Boot] @Transactional의 함정: 롤백(Rollback)과 전파 속성의 모든 것 은행 앱에서 A가 B에게 10만 원을 송금하는 상황을 상상해 봅시다. 서버는 두 가지 쿼리를 실행합니다. 1. A의 통장에서 10만 원 차감 (UPDATE), 2. B의 통장에 10만 원 증가 (UPDATE). 그런데 1번 쿼리가 성공한 직후, 갑자기 데이터베이스 서버의 전원이 나갔습니다! A의 돈은 10만 원이 증발했는데, B는 돈을 받지 못했습니다. 뉴스에 대서특필될 만한 엄청난 사고입니다. 이런 대형 사고를 막기 위해 데이터베이스는 "1번과 2번 쿼리를 하나로 묶어라. 둘 다 성공할 때만 최종 반영(Commit)하고, 하나라도 실패하면 1번 쿼리도 아예 없었던 일로 롤백(Rollback) 시켜라!"라는 논리적 작업 단위를 제공하는데, 이것이 바로 트랜잭션(Transaction)입니다. 스프링 부트(.. [Spring Boot] OAuth 2.0 소셜 로그인: 카카오, 네이버, 구글 연동의 정석 인터넷 쇼핑몰이나 새로운 서비스에 접속했을 때, 여러분은 긴 회원가입 폼을 성실하게 채우시나요, 아니면 "카카오로 1초 만에 시작하기" 버튼을 누르시나요? 바쁘고 귀찮은 것을 극도로 싫어하는 현대의 유저들에게 자사몰의 독자적인 회원가입(ID/PW)을 강요하는 것은 곧 '고객 이탈'을 의미합니다. 이러한 이탈을 막기 위해 구글, 카카오, 네이버 같은 거대 IT 기업들이 유저의 신원을 대신 확인해 주고 우리 서버에 "이 사람 진짜 맞아!"라고 보증을 서주는 기술이 등장했습니다. 바로 OAuth 2.0 (Open Authorization) 프로토콜입니다. 그리고 스프링 부트(Spring Boot) 진영에는 이 복잡한 프로토콜 통신을 아주 우아하게 캡슐화해 놓은 spring-boot-starter-oauth2-.. [Spring Boot] Spring Security 2편: 현대 API 인증의 표준, JWT(JSON Web Token) 완벽 구현 앞선 14단계에서 우리는 스프링 시큐리티(Spring Security)의 위대한 필터 체인(Filter Chain)과 전통적인 폼 로그인(Session/Cookie 방식)을 마스터했습니다. 세션 기반 로그인은 보안성이 높고 구현이 편하지만, 현대의 트렌드인 '모바일 앱(iOS/Android) 통신'과 서버 수십 대를 띄우는 '마이크로서비스(MSA) 스케일 아웃' 환경을 만나면 치명적인 약점을 드러냅니다. 사용자가 서버 A에 로그인하여 세션을 만들었는데, 다음 요청이 서버 B로 향하면 서버 B는 "너 누구야?" 라며 로그아웃 시켜버리기 때문입니다(세션 불일치). 이 골치 아픈 '상태 유지(Stateful)'의 사슬을 끊어내고, 서버가 사용자 정보를 기억할 필요 없이 "네가 가진 암호화된 방문증(Token).. [Spring Boot] Spring Security 1편: 거대한 철문, 폼 로그인(Form Login)과 아키텍처의 이해 웹 서비스를 운영하다 보면 "로그인한 회원만 글을 쓸 수 있게 해라", "관리자(Admin) 권한이 있는 사람만 이 페이지에 접근하게 해라"와 같은 요구사항이 쏟아집니다. 초보 개발자들은 컨트롤러(Controller)의 모든 메서드 첫 줄에 if (session.getAttribute("user") == null) throw new Error(); 같은 코드를 복붙하며 지옥을 맛보곤 합니다. 이처럼 중복되는 보안(Security) 검사 로직을 애플리케이션의 핵심 비즈니스 로직과 완벽하게 분리하여, 개발자가 비즈니스에만 집중할 수 있게 해주는 전 세계에서 가장 강력하고 튼튼한 방패가 바로 Spring Security(스프링 시큐리티)입니다. 하지만 그 강력함만큼이나 초기 진입 장벽이 악명 높게 높은 것으로.. [Spring Boot] Redis 캐싱(Caching): DB 부하를 박살내고 응답 속도 10배 끌어올리기 스타트업이 처음 런칭했을 때는 유저가 적어 데이터베이스(RDB) 하나만으로도 충분히 서비스가 잘 돌아갑니다. 하지만 마케팅이 대박 나서 '초당 1만 건'의 요청이 쏟아지기 시작하면 상황은 달라집니다. 여러분이 앞선 12단계에서 HikariCP 커넥션 풀을 아무리 완벽하게 튜닝해 놓았더라도, 물리적인 디스크(Disk)를 긁어서 데이터를 읽어오는 관계형 데이터베이스(MySQL, Oracle)는 태생적으로 속도의 한계가 있습니다. 특히 '쇼핑몰 메인 페이지의 배너 이미지 목록'이나 '오늘의 인기 검색어'처럼 수많은 유저가 똑같이 조회하지만, 데이터는 하루에 한두 번만 변하는 정보를 매번 느린 디스크 DB까지 내려가서 읽어오는 것은 엄청난 리소스 낭비입니다. 이를 해결하기 위해 백엔드 진영이 도입한 궁극의 마법.. ← 이전 1 2 3 다음 →