Spring/스프링으로 시작하는 리액티브 프로그래밍 16

[Spring WebFlux] 예외 처리

서론Spring MVC 기반의 애플리케이션에서는 @ExceptionHandler 혹은 @ControllerAdvice 등의 애너테이션을 이용하여 예외 처리를 진행했습니다.Spring WebFlux 기반의 애플리케이션에서도 두 애너테이션을 사용 가능하지만 이번 게시글에서는 Spring WebFlux 전용 예외 처리 기법에 대해 간단하게 정리해 보겠습니다. Reactor에서 제공하는 에러 처리 Operator를 이용한 예외 처리자주 사용하는 Operator로 error, onErrorReturn, onErrorResume, onErrorContinue, retry가 있으며 해당 Operator들을 통해 inline 예외 처리 수행사용하기 쉽고 간편하지만클래스 내 여러 개의 Sequence가 존재할 때 각 S..

Spring Data R2DBC 간단 정리

R2DBC (Reactive Relational Database Connectivity)관계형 데이터베이스에 리액티브 프로그래밍 API를 제공하기 위한 개방형 사양(Specification)드라이버 벤더가 구현하고 클라이언트가 사용하기 위한 SPI(Service Provider Interface)R2DBC의 등장으로 관계형 데이터베이스를 사용하더라도 클라이언트의 요청부터 데이터베이스 접근까지 완전한 non-blocking 애플리케이션을 구현하는 것이 가능해짐 1. R2DBC를 지원하는 드라이버 목록ClilckHouse R2DBC DriverGoogle Cloud SpannerJasync-sql MySQLOracle R2DBC DriverR2DBC H2R2DBC MariaDBR2DBC MySQLR2DBC ..

[Spring WebFlux] 함수형 엔드포인트(Functional Endpoint)

서론Spring WebFlux는 지난 게시글에서 소개했다시피 Spring MVC와 같은 애너테이션 기반 프로그래밍 모델과 함께 함수형 엔드포인트를 기반으로 하는 새로운 프로그래밍 모델을 지원합니다.함수형 엔드포인트에서는 들어오는 요청을 라우팅하고, 라우팅 된 요청을 처리하며 결과 값을 응답으로 반환한 등의 모든 작업을 하나의 함수 체인에서 처리합니다.이번 게시글에서는 함수형 엔드포인트 프로그래밍 모델에 대해 간단하게 알아보겠습니다. HandlerFunction을 사용한 요청 처리함수형 엔드포인트는 인입되는 요청을 처리하기 위해 HandlerFunction이라는 함수형 기반의 핸들러를 사용합니다.서블릿 기반의 요청 처리는 Servlet 인터페이스의 service 메서드의 파라미터로 전달받는 ServletR..

[Spring WebFlux] 애너테이션 기반 컨트롤러

컨트롤러 관점에서 Spring MVC vs Spring WebFlux 1. Spring MVC Controller@RequestBody 애너테이션을 지정해서 클라이언트의 요청 데이터를 전달받고, ResponseEntity 클래스를 이용해 응답 데이터를 클라이언트에게 전달하는 전형적인 Spring MVC 기반 Controller  2. Spring WebFlux Controller겉보기에는 단순히 Mono와 Flux로 wrapping 한 것처럼 보이지만 non-blocking을 지원하는 리액티브 핸들러애너테이션 기반의 프로그래밍 모델은 기존의 Spring MVC 구조와 거의 흡사하게 사용할 수 있음  Spring WebFlux 기반의 컨트롤러 사용 시 주의할 점 1. Repository/Service 계층..

[Reactor] 자주 사용되는 Operator

Operator리액티브 프로그래밍은 Operator로 시작해서 Operator로 끝난다고 해도 과언이 아님Operator는 데이터 스트림의 요소에 대해 변환, 필터링, 결합 등의 다양한 작업을 수행할 수 있는 함수형 프로그래밍 구성 요소Operator는 주어진 데이터 스트림(또는 Publisher)의 각 요소에 대해 특정 작업을 수행한 후, 그 결과를 새로운 데이터 스트림으로 반환하는 함수새로운 데이터 스트림 역시 다른 Operator의 입력으로 사용될 수 있으며, 이를 통해 복잡한 데이터 처리 파이프라인을 구축할 수 있음 Sequence 생성을 위한 Operator 1. justOrEmptyjust()의 확장 Operatorjust() Operator와 달리 emit 할 데이터가 null일 경우 NPE..

[Spring] Spring WebFlux 개요

Spring WebFlux 탄생 배경리액티브 웹 애플리케이션 구현을 위해 Spring 5.0부터 지원하는 리액티브 웹 프래임워크기술의 발달에 따른 대량의 요청 트래픽을 Spring MVC 방식이 처리하지 못하는 상황이 잦아짐에 따라 적은 수의 쓰레드로 대량의 요청을 안정적으로 처리할 수 있는 비동기 Non-Blocking I/O 방식의 Spring WebFlux가 탄생 Spring Reactive Stack주요 구성 요소설명Netty, Servlet 3.1+ ContainersNetty: 네트워크 애플리케이션 프레임워크로 고성능 non-blocking 서버를 구현하는데 사용Servlet 3.1+ Containers: Servlet API 3.1 이상을 지원하는 컨테이너로 non-blocking I/O를 ..

[Reactor] Reactor 테스트

서론Reactor에서는 reactor-test라는 테스트 전용 모듈을 통해 여러 가지 유형의 테스트를 지원합니다.reactor-test 모듈의 기능을 사용하기 위해서는 build.gradle 파일의 dependencies에 다음 의존성을 추가해야 합니다. testImplementation 'io.projectreactor:reactor-test' 1. StepVerifier를 사용한 테스트Reactor에서 가장 일반적인 테스트 방식은 Flux 혹은 Mono를 Reactor Sequence로 정의한 후 구독 시점에 해당 Operator 체인이 시나리오대로 동작하는지를 테스트하는 방식이며 이를 위해 StepVerifier라는 API를 제공합니다.ex) Reactor Sequence에서 다음에 발생할 시그널이..

[Reactor] Reactor Sequence 디버깅 방법

서론동기식 또는 명령형 프로그래밍 방식은 예외가 발생했을 때 Stacktrace를 확인하거나 예외 발생이 예상되는 코드에 브레이크 포인트를 걸어서 문제가 발생한 원인을 단계적으로 찾아가면 되기 때문에 상대적으로 디버깅 난이도가 쉽습니다.하지만 Reactor의 경우 코드 자체는 선언형 프로그래밍 방식으로 작성하지만 작업들이 대부분 비동기적으로 실행되기 때문에 디버깅 난이도가 상대적으로 어렵습니다.이번 게시글에서는 디버깅 난이도를 낮추기 위해 Reactor에서 제공하는 몇 가지 방법을 간단히 소개하겠습니다. 1. Debug 모드 사용Reactor에서의 디버그 모드 활성화는 Hooks.onOperatorDebug()를 통해 이루어집니다.우선 디버그 모드를 활성화하지 않을 경우 디버깅하기 어렵다는 것을 증명하기..

[Reactor] Context

Context프로그래밍 세계에서의 Context는 어떠한 상황을 처리하거나 해결하기 위해 필요한 정보를 제공하는 어떤 것ex) Spring Security에서 SecurityContextHolder는 SecurityContext를 관리하는 주체, 여기서의 SecurityContext는 애플리케이션 사용자의 인증 정보를 제공하는 인터페이스ex) Spring Framework에서 ApplicationContext는 애플리케이션의 정보를 제공하는 인터페이스로 ApplicationContext에서 제공하는 대표적인 정보가 Spring Bean Reactor에서 Context는 각 리액티브 시퀀스의 실행 시점에 관련된 데이터를 보관할 수 있는 불변 데이터 구조Map과 유사한 key-value 쌍의 형태로 데이터를..

[Reactor] Scheduler

SchedulerOS에서 사용되는 Scheduler와 의미가 비슷OS 레벨에서의 Scheduler는 실행되는 프로그램인 프로세스를 선택하고 실행하는 등 프로세스의 라이프 사이클을 관리해 주는 관리자 역할Reactor의 Scheduler는 비동기 프로그래밍을 위해 사용되는 쓰레드를 관리해 주는 역할Scheduler를 사용하여 어떤 쓰레드에서 무엇을 처리할지 제어Reactor Scheduler를 사용하면 코드 자체가 매우 간결해지고 Scheduler가 쓰레드의 제어를 대신해 주기 때문에 멀티 쓰레드 환경에서의 예상치 못한 오류가 발생할 확률을 최소화시킬 수 있음 Scheduler를 위한 전용 OperatorReactor에서 Scheduler는 Scheduler 전용 Operator를 통해 사용할 수 있음su..