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

[Spring WebFlux] Reactive Streaming 데이터 처리

개요Spring WebFlux는 SSE(Server-Sent Events)를 이용해 데이터를 Streaming 할 수 있습니다.SSE는 spring 4.2 버전부터 지원되었으며 Spring 5 버전부터 Reactor의 Publisher 타입인 Flux를 이용해 조금 더 편리한 방법으로 SSE를 사용할 수 있게 되었습니다. SSE서버가 클라이언트에게 단방향 스트리밍으로 데이터를 전송하는 방식WebSocket은 양방향 통신이 가능한 기술이지만 SSE는 단방향 클라이언트는 한 번 연결을 수립한 후 서버에서 발생하는 이벤트나 업데이트를 지속적으로 받아볼 수 있으며 주로 실시간 데이터 전송이 필요한 애플리케이션에서 사용됨SSE는 기존의 HTTP 프로토콜 위에서 동작하고 웹 브라우저에서 표준적으로 제공되며, tex..

[Spring WebFlux] WebClient

WebClient비동기적이고 non-blocking 방식으로 HTTP 요청을 처리할 수 있는 클라이언트전통적인 Spring MVC의 RestTemplate의 대안으로 Spring 5부터 지원하는 non-blocking HTTP 요청을 위한 리액티브 웹 클라이언트로서 함수형 기반의 향상된 API 제공비동기적 호출 외에도 block() 메서드를 사용하여 동기적으로 데이터를 받을 수 있지만 WebFlux 환경에서는 가능한 비동기 방식으로 사용하는 것이 성능에 유리 WebFlux 환경에서의 고성능, 비동기적 애플리케이션 개발을 위해 설계됐으며 기본 HTTP 클라이언트 라이브러리는 Reactor NettyWebClient는 Mono와 Flux를 지원하여, 리액티브 스트림을 통해 데이터를 처리Mono는 하나의 요소..

[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()를 통해 이루어집니다.우선 디버그 모드를 활성화하지 않을 경우 디버깅하기 어렵다는 것을 증명하기..