대규모 트래픽을 견디는 백엔드 세션(Session) 기반 인증 vs JWT 토큰 인증 비교

대규모 트래픽을 견디는 백엔드 세션(Session) 기반 인증 vs JWT 토큰 인증 비교

지난 8편 글에서는 스프링 시큐리티의 핵심 동작 원리와 내부 인증 흐름을 살펴보았습니다. 유저의 아이디와 비밀번호가 맞는지 검증하는 ‘인증’을 마쳤다면, 이제 다음 단계는 “이 사용자가 로그인 상태라는 것을 서버가 어떻게 기억하고 유지할 것인가?”에 대한 아키텍처 선택입니다. 전통적인 웹 애플리케이션에서는 서버의 메모리를 활용하는 세션(Session) 방식을 주로 사용해 왔습니다. 하지만 현대의 대규모 트래픽을 처리하는 마이크로서비스 아키텍처(MSA)나 앱 환경에서는 … 더 읽기

Spring Security의 기본 동작 원리와 인증/인가 흐름

Spring Security의 기본 동작 원리와 인증인가 흐름 파헤치기

웹 애플리케이션을 구축할 때 결코 타협할 수 없는 가장 중요한 요소는 바로 ‘보안(Security)’입니다. 자바 백엔드 생태계에서 스프링 부트(Spring Boot)로 개발을 진행할 때, 회원가입, 로그인, 접근 권한 제어 등 보안 기능을 구현하기 위해 필수적으로 사용하는 프레임워크가 바로 스프링 시큐리티(Spring Security)입니다. 스프링 시큐리티는 막강하고 유연한 기능을 제공하지만, 내부 아키텍처와 구동 원리를 모른 채 설정 코드만 복사해서 사용하면 … 더 읽기

스프링 인터셉터(Interceptor)와 서블릿 필터(Filter)의 차이점 및 활용법

스프링 인터셉터(Interceptor)와 서블릿 필터(Filter)의 차이점 및 활용법

자바 기반의 웹 애플리케이션을 개발하다 보면 로그인 여부 체크, 권한 확인, XSS(크로스 사이트 스크립팅) 방어, 요청 로그 기록 등 모든 HTTP 요청에서 공통으로 처리해야 하는 전처리 작업이 발생합니다. 이때 비즈니스 로직이 포함된 컨트롤러(Controller)마다 동일한 코드를 중복해서 작성하는 것은 객체 지향 설계에 위배됩니다. 스프링 부트(Spring Boot) 웹 아키텍처에서는 이러한 공통 관심사를 일괄 처리하기 위해 서블릿 필터(Servlet … 더 읽기

자바 개발자가 알아야 할 DB 트랜잭션 격리 수준과 @Transactional 원리

자바 개발자가 알아야 할 DB 트랜잭션 격리 수준과 @Transactional 원리

자바 백엔드 개발을 진행하다 보면 데이터의 정밀함과 안전성을 지키기 위해 스프링(Spring)이 제공하는 @Transactional 어노테이션을 밥먹듯이 사용하게 됩니다. 이 한 줄의 코드는 데이터베이스(DB)의 핵심 속성인 ACID(원자성, 일관성, 격리성, 지속성)를 유지해 주는 강력한 무기입니다. 하지만 실무에서 대량의 트래픽이 발생하거나 여러 사용자가 동시에 동일한 데이터를 수정하려고 하면, 데이터가 꼬이거나 엉뚱한 값이 조회되는 부작용이 발생하곤 합니다. 이는 트랜잭션의 ‘격리 … 더 읽기

JPA N+1 문제, 직접 재현하고 쿼리 수까지 측정해봤다 (11번 → 1번)

JPA N+1 문제 원인 분석

JPA의 N+1 문제는 백엔드 면접 단골이자 실무 성능 장애의 흔한 원인입니다. “연관 엔티티를 조회할 때 쿼리가 N번 더 나간다”는 설명은 많지만, 이 글에서는 실제로 Spring Boot 프로젝트를 띄워 쿼리가 몇 번 나가는지 직접 측정했습니다. 숫자와 실제 Hibernate 로그로 확인합니다. 실험 환경 Spring Boot 3.3.5 / Java 21 / Spring Data JPA / H2(인메모리) 엔티티: Team … 더 읽기

자바 스레드 풀(Thread Pool)의 원리와 스프링 @Async 비동기 처리

자바 스레드 풀(Thread Pool)의 원리와 스프링 @Async 비동기 처리

지난 글에서는 멀티스레드 환경에서 발생하는 동시성 문제와 이를 해결하기 위한 동기화 기법들을 알아보았습니다. 자바 백엔드 애플리케이션은 수많은 사용자 요청을 처리하기 위해 멀티스레드를 활용하지만, 요청이 들어올 때마다 스레드를 새로 생성하고 바꾸는 것은 서버에 엄청난 부담을 줍니다. 실무에서는 이러한 자원 낭비를 막고 대량의 요청을 효율적으로 관리하기 위해 ‘스레드 풀(Thread Pool)’을 사용합니다. 또한, 스프링 프레임워크에서는 이를 기반으로 무거운 … 더 읽기

자바 동시성(Concurrency)과 멀티스레드 환경의 동기화 문제

자바 동시성(Concurrency)과 멀티스레드 환경의 동기화 문제

자바 백엔드 개발자라면 실무에서, 혹은 대기업 기술 면접에서 반드시 마주치게 되는 핵심 주제가 있습니다. 바로 ‘동시성(Concurrency)’과 ‘멀티스레드(Multi-Thread)’입니다. 스프링 프레임워크(Spring Framework) 기반의 백엔드 서버는 기본적으로 수많은 사용자의 요청을 멀티스레드 방식으로 처리합니다. 즉, 우리가 작성한 코드가 여러 스레드에 의해 동시에 실행된다는 뜻입니다. 이때 동시성 문제를 제대로 제어하지 못하면 데이터가 유실되거나 결제 오류가 발생하는 등 치명적인 금융·비즈니스 장애로 … 더 읽기

Java 가비지 컬렉션(Garbage Collection) 작동 원리와 알고리즘

Java 가비지 컬렉션(Garbage Collection) 작동 원리와 알고리즘

지난 글에서는 JVM의 핵심 메모리 영역인 스택(Stack)과 힙(Heap) 영역의 구조에 대해 알아보았습니다. new 연산자를 통해 생성된 객체들은 모두 힙 영역에 저장된다고 설명해 드렸는데요. 그렇다면 이 힙 영역에 쌓이는 객체들은 언제, 어떻게 메모리에서 해제될까요? C나 C++ 같은 언어에서는 개발자가 직접 free() 같은 함수를 호출해 메모리를 해제해야 합니다. 반면, 자바(Java)에서는 가비지 컬렉터(GC, Garbage Collector)가 더 이상 사용되지 … 더 읽기

Java JVM의 기본 구조 – JVM Stack과 Heap 메모리 영역

Java JVM의 기본 구조 - JVM Stack과 Heap 메모리 영역

자바(Java) 백엔드 개발자로서 애플리케이션을 안정적으로 운영하고 성능을 최적화하기 위해서는 자바 가상 머신(JVM, Java Virtual Machine)의 메모리 구조를 명확히 이해해야 합니다. 우리가 작성한 코드가 실행될 때 메모리에서 어떤 일이 일어나는지 모른다면, 실무에서 자주 발생하는 OutOfMemoryError나 성능 저하 문제를 해결할 수 없습니다. 본 글에서는 JVM의 핵심 메모리 영역인 런타임 데이터 영역(Runtime Data Area)의 구조를 살펴보고, 그중에서도 가장 … 더 읽기