본문 바로가기

분류 전체보기142

System.out.println()의 성능 이슈와 Logback 비교 실제 사례한 번 요청 시 5000명의 사용자를 요청하고, 처리 과정에서 응답시간이 20초 걸리는 사이트가 있는데, 원인을 알아보니 5000명의 정보를 다 System.out.println()으로 처리하고 있던 것이다. 이는 System.out.println()을 줄임으로써 응답시간이 6초까지 줄었다.- 이상민, 자바 성능 튜닝이야기, 인사이트, 201320초에서 6초로, 14초가 단축되었습니다. 정말 이게 가능한 일일까요?System.out.println()이 느린 이유1. 동기화(Synchronized) 오버헤드System.out.println()은 내부적으로 PrintStream의 synchronized 메서드를 사용합니다. javapublic void println(String x) { sy.. 2026. 1. 15.
@Async 적용하기 1. @Async란?@Async는 메서드를 별도의 스레드에서 비동기로 실행하게 해주는 Spring AOP 기능입니다.동기 vs 비동기 java// 동기 처리public void sendEmail(String email) { emailService.send(email); // 완료될 때까지 대기 (5초) System.out.println("다음 작업"); // 5초 후 실행}// 비동기 처리@Asyncpublic void sendEmail(String email) { emailService.send(email); // 별도 스레드에서 실행}public void process() { sendEmail("test@example.com"); System.out.println(".. 2026. 1. 14.
커넥션 타임아웃과 리드 타임아웃 HTTP 통신을 하다 보면 Connection Timeout과 Read Timeout이라는 용어를 자주 접하게 됩니다. 두 타임아웃 모두 네트워크 통신에서 발생하지만, 각각 다른 단계에서 적용됩니다. 이 글에서는 두 타임아웃의 차이점과 실무에서 알아야 할 내용들을 정리했습니다.커넥션 타임아웃 vs 리드 타임아웃커넥션 타임아웃 (Connection Timeout)TCP 연결을 맺는 과정에서의 제한 시간입니다.클라이언트가 서버에 연결 요청 시작TCP 3-way handshake 완료까지 대기하는 시간서버가 응답하지 않거나 네트워크가 불안정할 때 발생일반적으로 짧게 설정 (3~5초)// RestTemplate 예시HttpComponentsClientHttpRequestFactory factory = n.. 2026. 1. 13.
실행계획과 인덱스 1. 실행계획은 어떻게 읽어야 하나실행계획은 위에서 아래로 읽지 않는다. 안쪽(오른쪽, 가장 아래)부터 바깥쪽으로 실행된다.즉, 성능은 항상 첫 테이블 접근 방식에서 대부분 결정된다.2. 실행계획에서 반드시 봐야 하는 핵심 지표Rows (Cardinality)옵티마이저가 "이 단계에서 몇 건이 나올 것"이라 예상한 값실행계획의 모든 판단 기준Rows가 틀리면 조인 방식, 인덱스 선택, 실행 순서 전부 틀어진다.E-Rows vs A-RowsE-Rows: 예상 행 수A-Rows: 실제 실행 행 수5~10배 이상 차이면 무조건 튜닝 대상3. 테이블 접근 방식 한 줄 요약TABLE ACCESS FULL→ 테이블 전체를 읽음. 대량 데이터면 위험 신호TABLE ACCESS BY ROWID→ 인덱스로 위치를 찾은 .. 2025. 12. 16.
실서비스에서 커넥션 풀(hikari Cp) 제대로 이해하기 이 글은 실서비스 운영 중 발생한 커넥션 풀 이슈를 바탕으로, HikariCP + Spring + MyBatis 환경에서 커넥션 풀이 어떻게 동작하는지, 어떤 설정이 실제로 의미가 있는지 정리한 글이다.1. 커넥션 풀이 부족해지는 대표적인 원인실무에서 커넥션 풀 이슈의 원인은 거의 정해져 있다.커넥션 반환 누락 (close 안 됨)트랜잭션 범위가 과도하게 큼오래 걸리는 쿼리로 커넥션 점유 시간이 김풀 사이즈를 DB 한계보다 크게 설정중요한 점은 "풀 크기가 작아서" 발생하는 경우는 생각보다 적다는 것이다.2. SqlSessionTemplate를 쓰고 있다면@Primary@Beanpublic SqlSessionTemplate sqlSessionTemplate(@Qualifier("node01SessionF.. 2025. 12. 16.
Business Exception vs System Exception 1. 개요예외를 구분하는 이유: 성격과 처리 방식이 다르기 때문이다.Business Exception: 업무/사용자 관련 문제, 예측 가능System Exception: 시스템/인프라 문제, 예측 불가능2. Business Exception (업무 예외)사용자 또는 비즈니스 로직 문제예: 잔액 부족, 상품 없음, 권한 없음처리: 전역 핸들러에서 HTTP 400~409 수준 응답, 사용자 친화 메시지 제공 public class InsufficientBalanceException extends RuntimeException { public InsufficientBalanceException(String message) { super(message); } } 3. System Exception (시스템 예외.. 2025. 12. 15.
Spring @ControllerAdvice 완전 정리 1. 개요@ControllerAdvice는 컨트롤러 전역에서 발생하는 예외, 모델, 바인딩 등을 한 곳에서 처리하기 위한 스프링 어노테이션이다.실무에서는 대부분 전역 예외 처리용으로 사용된다.2. 주요 용도전역 예외 처리모든 컨트롤러에서 발생하는 예외를 한 곳에서 잡아서 일관된 응답 반환 @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public ResponseEntity handleAll(Exception ex) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body("서버 오류: " + ex.getMessage()).. 2025. 12. 15.
Spring @Transactional Propagation 완전 정리 1️⃣ 기본 개념트랜잭션: DB 작업 단위를 묶어 commit/rollback을 보장Propagation: 메서드 호출 시 이미 존재하는 트랜잭션을 어떻게 처리할지 지정 @Transactional public void doSomething() { // 기본값 REQUIRED 적용 } 아무 설정 안 하면 REQUIRED가 기본값의미: 기존 트랜잭션 참여, 없으면 새 생성2️⃣ 주요 Propagation 옵션옵션동작예시/사용 이유REQUIRED기본값. 기존 트랜잭션 참여, 없으면 새 생성일반 CRUD 메서드REQUIRES_NEW항상 새 트랜잭션 생성, 기존 트랜잭션 일시 중단로그, 결제, 독립 commit 필요 시SUPPORTS기존 트랜잭션 있으면 참여, 없으면 트랜잭션 없이 실행선택적 트랜잭션 처리NOT_.. 2025. 12. 15.
외부 API 장애에도 우리 서비스가 죽지 않게 하는 방법 외부 API가 느려지거나 일시적으로 장애가 나면, 우리 서비스도 스레드가 묶이면서 전체가 느려지거나 다운될 수 있다.이걸 방지하기 위해 사용하는 패턴과 기술을 정리한다.1. 문제 정의동기 호출 구조에서는 외부 호출이 느려지면 우리 서비스 스레드가 대기함DB 커넥션이나 스레드 풀 고갈로 서비스 전체 장애로 확산단순 try-catch는 예외만 잡고 끝 → 스레드는 여전히 묶임2. 기본 방어책: Timeout + Fallback타임아웃외부 호출이 오래 걸리면 강제로 중단스레드 반환 → 다른 요청 처리 가능Fallback외부 호출 실패 시 대체 응답 제공캐시, 기본값, 빈 목록 등서비스 죽지 않고 최소 기능 유지 try { return callExternalApi(); } catch (Exception e) {.. 2025. 12. 15.