Spring 9

[Test] 부하 테스트(Load Test)란?

무엇인가? 특정 수준의 트래픽을 시스템이 안정적으로 처리할 수 있는지 검증하는 과정왜 해야 하는가?1. 다음 상황을 방지하기 위해CPU 100%DB Connection 부족Redis 요청 지연Kafka Consumer Lag 증가API 실패율 증가서비스 전체 장애2. 기능 테스트로 발견되지 않는 문제 조기 발견Consumer 처리 속도 부족DB insert 병목Redis ZSET 업데이트 지연Thread pool 부족Memory leak으로 장기 요청 지연3. 병목 지점을 찾아 성능 개선의 단서를 얻기 위해병목 지점원인API 레이어Tomcat 스레드 부족서비스 레이어동기 처리 지연KafkaConsumer 처리 속도 부족DBconnection pool 부족Redis명령 처리 지연 무엇이 있는가Stress ..

Spring 2026.04.01

[Spring] DB 조회에서 인덱스의 효과

1. 인덱스의 개념과 특성개념인덱스는 쿼리 성능을 높이는 도구이다.인덱스가 없이 특정 데이터를 조회하기 위해선 테이블 내 모든 데이터를 일일이 확인해야 한다. 이를 Full Table Scan이라고 한다.인덱스를 활용하면 색인표를 활용하기 때문에 매우 빠르게 조회할 수 있다. 이를 Index Scan이라고 한다.제약색인표는 기존 테이블과 별도의 공간에서 관리되기 때문에, 추가 공간이 필요하다.트리 구조로 인해, Full Table Scan 방식 대비 insert와 update 과정에 시간이 많이 소요된다.2. 인덱스의 작동 방식인덱스는 컬럼 단위로 생성된다.인덱스가 생성된 컬럼은 Index Scan이 가능하지만, 그렇지 않은 컬럼은 인덱스를 활용할 수 없다.3. Index Scan의 종류다양한 Index..

Spring 2026.02.26

[Spring AI] LLM, call(), stream(), 모델의 확률성

1. LLM과 호출 방법LLM 객체란, 모델과의 통신 방식을 추상화한 클래스이다. LLM 객체를 호출하는 메서드는 call(), stream() 두 가지가 있다. 2. Call()call()은 짧은 응답이나 배치 처리에 적합하다. 사용자는 대기 후 답변을 한 번에 받을 수 있다. 응답을 db에 저장할 때, 응답 결과로 다음 로직을 실행할 때(스텝 백 프롬프트)에도 call()이 유리하다. 3. Stream()stream()은 응답을 기다리지 않고 생성되는 즉시 수신한다. 때문에 실시간으로 타이핑되듯 표시된다.실시간 채팅이나 긴 응답인 경우 적합하다. 이때 응답은 청크 단위로 반환한다. 실제로 call()은 stream()을 내부에서 사용하고 모든 chunk를 모아서 반환하는 방식으로 구현되는 경우가 많다..

Spring 2026.02.26

[Spring] Java와 Redis를 연결해주는 RedisTemplate

Redis 학습 정리1장 - Redis, RedisTemplateRedis는 메모리 기반의 빠른 DB이다.Java 기반 Spring Boot 프로젝트에서 Redis를 사용하기 위해선, Java와 Redis를 연결해주는 역할이 필요하다.이를 수행해주는 것이 RedisTemplate이다.RedisTemplate은 Java와 Redis 사이의 변환기라고 할 수 있다.Java 명령어를 Redis 명령어로 상호 변환하여 통신을 가능케 한다.2장 - Redis의 데이터 저장 방식과 직렬화 도구저장 방식Redis는 모든 데이터를 key-value 형태로 저장한다.이때 데이터 타입은 전부 문자열로 저장된다.직렬화 (Java → Redis)Java 객체를 Redis에 저장하기 위해서는 문자열 형태로 파싱해주는 작업이 필..

Spring 2026.02.26

[Spring] 동적 쿼리 - BooleanBuilder와 BooleanExpression의 차이

About this article: Today I learned - 오늘 배운 것들을 간단히 기록합니다. Article Body:두 방식 비교 요약구분BooleanBuilderBooleanExpression개념조건을 모아두는 컨테이너단일 조건의 표현식객체 성격가변(Mutable)불변(Immutable)null 처리직접 제어자동 무시where 작성 방식.where(builder).where(조건1, 조건2, 조건3..)재사용성낮음높음코드 가독성복잡함깔끔함 모두 데이터베이스 쿼리를 동적으로 생성하기 위해 사용 Trade-Off 관계:재사용성 + 가독성 -> BooleanExpression조건의 유연성 -> BooleanBuilder 예) 필터 조건이 많거나, 조건이 동적으로 추가되거나 제거되는 경우가 빈번한..

Spring 2026.02.24

[Spring] OSIV, N+1문제, LAZY와 EAGER

OSIV (Open Session In View)JPA/Hibernate에서 영속성 컨텍스트(Session)를 View 렌더링 시점까지 열어두는 기능Spring Boot에서는 기본값이 trueOSIV ON -> DB 커넥션을 API 응답이 완전히 끝날 때까지 유지OSIV OFF -> 트랜잭션이 끝나면 즉시 커넥션 반환 끄는 것이 좋은 이유커넥션 점유 시간 단축 : 커넥션 풀 효율 증가동시 처리량 향상 : 병목 발생 예방명확한 트랜잭션 경계 : 지연 로딩이 어디서든 발생할 수 있는 불명확함 제거끌 때의 단점(TRADEOFF)지연 로딩 사용 시 LazyInitializationException 발생 가능Fetch Join이나 DTO 변환을 명시적으로 처리해야 함KEY TAKEAWAY트래픽이 많은 서비스에서는..

Spring 2026.01.23

[Spring] Error creating bean with name 'jwtUtil': Injection of autowired dependencies failed, Could not resolve placeholder 'jwt.secret.key' in value "${jwt.secret.key}" 해결하기

Spring Boot 환경에서 JWT 라이브러리를 설정하고, JWT Util 클래스를 구현한 뒤 토큰 생성 기능을 테스트하기 위해 실행을 눌렀는데, 아래와 같은 에러가 발생했다.더보기Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled. 2026-01-21T15:02:24.048+09:00 ERROR 4420 --- [ main] o.s.boot.SpringApplication : Application run failed org.springframework.beans.factory.BeanCreat..

Spring 2026.01.21