Hye Jin Ryoo

[헥사고날 아키텍처] Day 2: Use Case와 Domain - 규칙을 어디에 둘 것인가

서론: Service가 모든 일을 하지 않게 하기 헥사고날 구조를 적용해도 Use Case 구현 안에 검증·계산·상태 변경이 모두 조건문으로 쌓이면 이름만 바뀐 거대한 Service가 된다. Use Case는 작업 순서를 조율하고, Domain은 자신의 상태와 규칙을 지키게 한다. 1. Use Case의 책임 입력 Command 해석 필요...

[헥사고날 아키텍처] Day 1: 의존성 방향 - 비즈니스를 프레임워크에서 분리하기

서론: Controller-Service-Repository만으로 부족할 때 계층형 구조는 시작하기 쉽지만 규모가 커지면 Service가 JPA Entity, HTTP Client, 메시지 발행을 모두 알게 되기 쉽다. 비즈니스 규칙을 테스트하려 해도 Spring Context와 DB가 필요해진다. 헥사고날 아키텍처의 핵심은 폴더 모양이 아니라 의존...

[JVM 성능] Day 5: JFR과 프로파일링 - 추측 없이 병목 찾기

서론: CPU가 높다는 것은 원인이 아니다 성능 사고에서 “GC 같다”, “DB 같다”는 가설일 뿐이다. 먼저 증상을 시간축에 고정하고, 비용이 낮은 지표에서 시작해 thread dump·JFR·heap dump처럼 더 깊은 증거로 내려간다. 도구는 많이 쓰는 것보다 질문에 맞는 것을 고르는 것이 중요하다. 1. 증상을 정확히 적기 언제: 14:...

[JVM 성능] Day 4: Virtual Thread - 더 많은 요청을 단순한 코드로 처리하기

서론: 가상 스레드는 요청을 빠르게 만들지 않는다 가상 스레드는 많은 동시 I/O 작업을 thread-per-request 스타일로 표현할 수 있게 한다. 블로킹 I/O 중 가상 스레드는 carrier 플랫폼 스레드에서 내려오고, carrier는 다른 작업을 실행한다. 장점은 개별 요청의 latency 감소보다 같은 하드웨어에서 기다리는 요청을 더 ...

[JVM 성능] Day 3: 스레드 풀과 Backpressure - 동시성을 제한하는 법

서론: 동시성은 속도가 아니라 대기열 관리다 스레드를 늘리면 동시에 더 많은 요청을 시작할 수 있지만 CPU·DB 연결·외부 API 용량이 늘어나는 것은 아니다. 처리 능력보다 입력이 많으면 어디엔가 대기열이 생긴다. 좋은 동시성 설계는 그 대기열의 위치·크기·거부 정책을 명시한다. 1. 스레드 풀의 네 요소 worker 수: 동시에 실...

[JVM 성능] Day 2: GC 튜닝 - 처리량과 지연 사이의 선택

서론: GC 옵션보다 목표가 먼저다 GC 튜닝은 플래그를 많이 붙이는 일이 아니다. 서비스가 원하는 최대 지연, 처리량, 메모리 비용을 정의하고 실제 GC 로그에서 목표를 벗어난 원인을 찾는 일이다. 일시 중지 50ms가 중요한 API와 밤새 처리량이 중요한 배치는 같은 Collector와 Heap 크기가 정답일 필요가 없다. 1. 세 가지 목표 ...

[Spring Batch 실전] Day 5: 테스트와 운영 - 결과를 증명하는 배치

서론: COMPLETED만으로 성공을 판단할 수 없다 프로세스가 오류 없이 끝났어도 일부 데이터가 빠지거나 금액 합계가 틀리면 배치는 실패다. 반대로 재시도 후 모든 업무 결과가 맞다면 중간 오류가 있어도 성공일 수 있다. 배치 운영은 프레임워크 상태와 업무 불변식을 함께 검증해야 한다. 1. 테스트 층위 단위 테스트: Processor의 변...

[Spring Batch 실전] Day 4: 병렬화와 파티셔닝 - 처리량을 안전하게 늘리기

서론: 스레드를 늘리기 전에 병목을 찾자 배치가 느리면 worker 수부터 늘리기 쉽다. 하지만 병목이 DB 쓰기나 외부 API 제한이라면 동시성 증가는 대기와 락만 키운다. 대표 데이터로 단일 스레드 성능을 측정하고 CPU·I/O·DB·네트워크 중 포화 지점을 찾은 뒤 병렬화한다. 1. 가장 단순한 최적화부터 필요한 컬럼만 읽기 N+1 ...