| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
- 정규식
- junit5
- html
- HashMap
- Array
- math
- 배열
- js
- Java
- 자바
- input
- 인텔리제이
- string
- 자바스크립트
- vscode
- java테스트
- ArrayList
- 문자열
- 테스트자동화
- Eclipse
- 스프링부트
- IntelliJ
- junit
- 자바문법
- 단위테스트
- list
- Visual Studio Code
- javascript
- SpringBoot
- CSS
- Today
- Total
목록IT/SpringBoot (101)
어제 오늘 내일
MVC에서는 쓰레드 하나가 막혀도(Blocking) 다른 쓰레드 199개는 잘 돌아갑니다.하지만 WebFlux는 쓰레드가 고작 CPU 코어 수(예: 4개)만큼밖에 없습니다. 하나가 막히면 서버 성능의 25%가 날아가는 셈이죠.문제는 실수로 JDBC를 쓰거나, Thread.sleep을 써도 컴파일 에러가 안 난다는 것입니다. 배포하고 나서야 서버가 죽는 걸 보게 되죠.이걸 막아주는 수호신, BlockHound를 소개합니다.1. BlockHound: "블로킹 코드가 보이면 에러를 뱉어라!"Reactor 팀이 만든 도구로, 논블로킹 쓰레드(Reactor Thread)에서 블로킹 작업이 감지되면 즉시 예외(BlockingOperationError)를 던져서 테스트를 실패하게 만듭니다.① 의존성 추가depende..
JUnit으로 동기 코드를 테스트할 때는 결과가 바로 나옵니다.하지만 Flux.interval(Duration.ofSeconds(1)) 같은 코드는 1초 뒤에 데이터가 나옵니다.이걸 테스트하려고 Thread.sleep(1000)을 쓰는 순간, 테스트 시간은 늘어지고 코드는 지저분해집니다.Project Reactor는 이런 문제를 해결하기 위해 StepVerifier라는 강력한 테스트 도구를 제공합니다.1. StepVerifier가 뭔가요?리액티브 스트림의 구독자(Subscriber) 역할을 하는 테스트용 객체입니다."첫 번째 데이터는 'A'여야 하고, 두 번째는 'B'여야 하고, 마지막엔 성공적으로 끝나야 해"라는 시나리오를 짜고, 실제로 그렇게 흘러가는지 검증합니다.2. 기본 사용법: 데이터 검증 ()..
WebFlux에서 R2DBC를 쓸 때 가장 불안한 점은 트랜잭션입니다."A 계좌에서 돈을 빼고(update), B 계좌에 돈을 넣어야(update) 하는데, 중간에 에러 나면 롤백이 될까?"결론부터 말씀드리면, @Transactional 어노테이션 하나면 완벽하게 동작합니다.하지만 그 원리는 MVC와 완전히 다릅니다.1. 트랜잭션 매니저 설정 ()스프링 부트가 ConnectionFactory를 보고 알아서 빈을 등록해 주지만, 명시적으로 알고 있어야 합니다.JDBC의 PlatformTransactionManager가 아니라, R2dbcTransactionManager가 필요합니다.@Configuration@EnableTransactionManagement // 트랜잭션 관리 활성화public class ..
WebFlux 서버를 잘 만들어놓고 spring-boot-starter-data-jpa 의존성을 추가하는 순간, 그 서버의 성능은 나락으로 떨어집니다.왜냐고요? WebFlux는 적은 수의 쓰레드(이벤트 루프)로 돌아가는데, JPA가 쿼리를 날리는 동안 그 소중한 쓰레드를 붙잡고 놔주지 않기(Blocking) 때문입니다.이벤트 루프가 멈추면 서버 전체가 멈춥니다.그래서 우리는 R2DBC라는 새로운 친구를 사귀어야 합니다.1. R2DBC가 뭔가요?Reactive Relational Database Connectivity의 약자입니다.MySQL, PostgreSQL, H2 같은 관계형 DB를 논블로킹(Non-Blocking) 방식으로 사용할 수 있게 해주는 표준 API입니다. JDBC: 결과가 나올 때까지 ..
오랫동안 사랑받아온 RestTemplate이 유지보수 모드(Maintenance Mode)로 들어갔다는 사실, 알고 계셨나요?스프링 팀은 대놓고 "앞으로는 WebClient를 쓰세요"라고 권장합니다.이유는 단순합니다. RestTemplate은 동기(Blocking) 방식이라서, 외부 API가 3초 걸리면 내 서버도 3초 동안 멈춰 있어야 하기 때문입니다.반면 WebClient는 요청만 보내고 딴 일을 하러 갈 수 있습니다. (Non-Blocking)1. WebClient 만들기 (Builder 패턴)WebClient는 불변(Immutable) 객체라서 쓰레드 안전(Thread-safe)합니다. 싱글톤 빈으로 등록해서 재사용하는 것이 좋습니다.@Configurationpublic class WebClien..
지난 시간에는 @RestController를 이용한 익숙한 방식을 배웠습니다. 하지만 WebFlux의 창시자들은 조금 더 Java 8+ 람다(Lambda)스러운 방식을 제안합니다.바로 함수형 엔드포인트(Functional Endpoints)입니다.이 방식은 "요청을 어디로 보낼지(Routing)"와 "어떻게 처리할지(Handling)"를 완벽하게 분리합니다.1. 두 가지 핵심: Router & Handler마치 지하철 노선도와 같습니다.RouterFunction (지도): "이 URL로 오면 저기로 가세요." (길 안내)HandlerFunction (목적지): "오셨군요. 제가 처리해 드릴게요." (실제 업무)MVC에서는 컨트롤러 안에 매핑(@GetMapping)과 로직이 섞여 있었지만, 여기서는 완전히..
WebFlux를 시작할 때 가장 큰 장벽은 "새로운 문법을 배워야 한다"는 두려움입니다.하지만 스프링 부트는 기존 MVC 스타일의 코드를 99% 재사용할 수 있게 해 줍니다.오늘 보여드릴 코드를 보면 "어? 이게 WebFlux라고? MVC랑 똑같은데?"라고 하실 겁니다.하지만 그 속은 완전히 다른 비동기 엔진(Netty)으로 돌아가고 있죠.1. 의존성 확인먼저 spring-boot-starter-web이 아니라 spring-boot-starter-webflux가 필요합니다.dependencies { implementation 'org.springframework.boot:spring-boot-starter-webflux' // implementation 'org.springframework.b..
데이터를 변환할 때 우리는 습관적으로 .map()을 씁니다.하지만 WebFlux 세계에서 DB를 조회하거나 외부 API를 호출할 때 .map()을 쓰면, 결과값으로 Mono> 같은 러시아 인형(중첩 구조)이 튀어나옵니다.이 껍질을 벗겨내고 알맹이만 쏙 빼내는 기술, flatMap이 필요한 순간입니다.1. 단순 변환의 제왕: mapmap은 동기적(Synchronous)이고, 1:1로 변환할 때 사용합니다.입력 데이터 T를 받아서 U로 바꿉니다.비유: 사과를 넣으면 -> 껍질 깎은 사과가 나옴.특징: 단순히 값을 가공하거나, 객체를 다른 객체로 매핑할 때 씁니다.// 1. 문자열을 대문자로 변환Flux.just("a", "b", "c") .map(String::toUpperCase) // "a" -> ..
MVC에서 List를 리턴하면 "유저 목록이구나", User를 리턴하면 "단건 조회구나"라고 바로 알 수 있죠.WebFlux에서도 마찬가지입니다. 리턴 타입만 봐도 "데이터가 몇 개 흐를지" 예측할 수 있어야 합니다.WebFlux의 기반 라이브러리인 Project Reactor는 데이터를 담는 그릇을 딱 두 가지로 정의했습니다.바로 Mono(모노)와 Flux(플럭스)입니다.1. Flux [0..N]: 끝없는 데이터의 강물Flux는 0개에서 N개(무한대 포함)의 데이터를 발행할 수 있는 Publisher입니다.비유: 컨베이어 벨트. 물건이 계속해서 지나갑니다.유사한 개념: List, Stream, Iterable용도:findAll(): DB에서 여러 건 조회실시간 주식 시세 (끝없이 데이터가 들어옴)로그 ..
자바 개발자에게 데이터란 무엇일까요? 보통 List, Map 같은 컬렉션에 담긴 "완성된 결과물"을 의미했습니다.DB에서 100만 건을 조회하면, 100만 건이 다 메모리에 올라올 때까지 기다렸다가 한 번에 List로 받아서 처리했죠. (Memory: "살려줘...")하지만 리액티브 프로그래밍(Reactive Programming)에서는 다릅니다.데이터는 고여있는 호수가 아니라, 끊임없이 흐르는 강물(Stream)과 같습니다.오늘은 WebFlux의 뼈대가 되는 표준 사양, 리액티브 스트림즈(Reactive Streams)와 그 핵심 기능인 백프레셔(Backpressure)를 알아보겠습니다.1. Iterable(과거) vs Reactive Streams(미래)가장 큰 차이는 "누가 주도권을 쥐고 있는가?"..
