스프링 리액터 시작하기 (2)

brian Byeon·2022년 4월 30일
0

0. 자료의 출처

https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-new-framework
오해가 없도록 어떤 text를 인용했는지 원문을 첨부합니다.🤗

1. 스프링 리액터가 무엇인가?

스프링 5는 두개의 웹 스택 중 선택해서 사용할 수 있다.
Reactive Stack을 사용하려면 Reactor가 필수이고, Netty와 같은 비동기/non-blocking 모델의 네트워킹 프레임워크를 사용하게 된다.

이제 기존의 동기식 서블릿 모델인 Tomcat과 같은 웹서버를 사용하려면 Servlet 3.1의 non-blocking IO를 지원하는 모델을 사용해야 한다.

Spring MVC의 역할을 해주는 Spring WebFlux 또한 비동기/non-blocking 모델이라서 DB에 대한 IO 시에 block하지 않도록 몽고DB와 같은 reactive DB를 지원한다.

1.1 왜 MVC 안쓰고 ?

>Spring MVC or WebFlux?

>A natural question to ask but one that sets up an unsound dichotomy. Actually, both work together to expand the range of available options. The two are designed for continuity and consistency with each other, they are available side by side, and feedback from each side benefits both sides. The following diagram shows how the two relate, what they have in common, and what each supports uniquely:
We suggest that you consider the following specific points:
- If you have a Spring MVC application that works fine, there is no need to change. Imperative programming is the easiest way to write, understand, and debug code. You have maximum choice of libraries, since, historically, most are blocking.
- If you are already shopping for a non-blocking web stack, Spring WebFlux offers the same execution model benefits as others in this space and also provides a choice of servers (Netty, Tomcat, Jetty, Undertow, and Servlet 3.1+ containers), a choice of programming models (annotated controllers and functional web endpoints), and a choice of reactive libraries (Reactor, RxJava, or other).
- If you are interested in a lightweight, functional web framework for use with Java 8 lambdas or Kotlin, you can use the Spring WebFlux functional web endpoints. That can also be a good choice for smaller applications or microservices with less complex requirements that can benefit from greater transparency and control.
- In a microservice architecture, you can have a mix of applications with either Spring MVC or Spring WebFlux controllers or with Spring WebFlux functional endpoints. Having support for the same annotation-based programming model in both frameworks makes it easier to re-use knowledge while also selecting the right tool for the right job.
- A simple way to evaluate an application is to check its dependencies. If you have blocking persistence APIs (JPA, JDBC) or networking APIs to use, Spring MVC is the best choice for common architectures at least. It is technically feasible with both Reactor and RxJava to perform blocking calls on a separate thread but you would not be making the most of a non-blocking web stack.
- If you have a Spring MVC application with calls to remote services, try the reactive WebClient. You can return reactive types (Reactor, RxJava, or other) directly from Spring MVC controller methods. The greater the latency per call or the interdependency among calls, the more dramatic the benefits. Spring MVC controllers can call other reactive components too.
- If you have a large team, keep in mind the steep learning curve in the shift to non-blocking, functional, and declarative programming. A practical way to start without a full switch is to use the reactive WebClient. Beyond that, start small and measure the benefits. We expect that, for a wide range of applications, the shift is unnecessary. If you are unsure what benefits to look for, start by learning about how non-blocking I/O works (for example, concurrency on single-threaded Node.js) and its effects.

우리가 왜 스프링 MVC에서 Spring Reactor로 옮겨야 하는 질문이 들수도 있지만, 기존 1개의 요청 별로 1개의 스레드를 생성하는 모델인 Spring MVC는 확장성에 한계가 있을 수 밖에 없으며 대량의 네트워크 통신시에 여러개의 스레드가 block 상태에 들어가서 다른 스레드를 더 만들어줘야 하는 불상사가 발생할 수도 있다.

사실 일반적인 웹 페이지들에 대해서는 성능상 더 안 좋을수도 있지만, scalability (확장성) 측면에서는 reactor가 더 이점을 가지고 있다고 보면 될 것이다.

1.2 Reactive가 뭔데?

>
We touched on “non-blocking” and “functional” but what does reactive mean?

>  The term, “reactive,” refers to programming models that are built around reacting to change — network components reacting to I/O events, UI controllers reacting to mouse events, and others. In that sense, non-blocking is reactive, because, instead of being blocked, we are now in the mode of reacting to notifications as operations complete or data becomes available.

> There is also another important mechanism that we on the Spring team associate with “reactive” and that is non-blocking back pressure. In synchronous, imperative code, blocking calls serve as a natural form of back pressure that forces the caller to wait. In non-blocking code, it becomes important to control the rate of events so that a fast producer does not overwhelm its destination.

> Reactive Streams is a small spec (also adopted in Java 9) that defines the interaction between asynchronous components with back pressure. For example a data repository (acting as Publisher) can produce data that an HTTP server (acting as Subscriber) can then write to the response. The main purpose of Reactive Streams is to let the subscriber control how quickly or how slowly the publisher produces data.

reactive는 변화에 맞춘 프로그래밍 모델을 일컫는다. 비동기는 reactive한 프로그래밍이라고 하는데, 하나의 네트워크 요청이 끝났다는 '신호'=='변화' 에 의해 다음 작용이 시작되기 때문이다.

또한 back pressure이 중요한 개념이다.동기적, 명령형 코드에서는 blocking call들이 함수를 호출한 사람이 기다려야 하는 back pressure로 작용한다. 즉 일반적으로 우리가 주도권을 갖고 있으니 흐름을 자유자재로 다뤄야 하는데, 이번엔 반대로 동기적 함수들이 우리보고 '기다려!' 하고 있는 것이다.😨

이제 non-blocking으로 들어오면서 우리들이 publisher (우리의 함수콜을 받는 쪽) 의 데이터를 우리가 원하는 속도, 흐름에서 제어가 가능해진다. non-blocking back pressure이 보다 예상가능한 상태가 되는 것이라 더 좋아진다고 보는 것 같다.

1.3 웹서버?

Spring WebFlux is supported on Tomcat, Jetty, Servlet 3.1+ containers, as well as on non-Servlet runtimes such as Netty and Undertow. All servers are adapted to a low-level, common API so that higher-level programming models can be supported across servers.

Spring WebFlux does not have built-in support to start or stop a server. However, it is easy to assemble an application from Spring configuration and WebFlux infrastructure and run it with a few lines of code.

Spring Boot has a WebFlux starter that automates these steps. By default, the starter uses Netty, but it is easy to switch to Tomcat, Jetty, or Undertow by changing your Maven or Gradle dependencies. Spring Boot defaults to Netty, because it is more widely used in the asynchronous, non-blocking space and lets a client and a server share resources.

Tomcat and Jetty can be used with both Spring MVC and WebFlux.
Keep in mind, however, that the way they are used is very different.Spring MVC relies on Servlet blocking I/O and lets applications use the Servlet API directly if they need to. Spring WebFlux relies on Servlet 3.1 non-blocking I/O and uses the Servlet API behind a low-level adapter. It is not exposed for direct use.

For Undertow, Spring WebFlux uses Undertow APIs directly without the Servlet API.

원래 Spring boot를 쓰는 것은 내장된 Tomcat을 사용하기 위함이라고도 할 수 있다. Spring WebFlux는 WebFlux starter를 두어서 (default = Netty) WebFlux infrastructure과 spring configuration으로부터 프로그램을 만들고, 실행시킬 수 있게 합니다. Netty가 asynchronous, non-blocking 환경에서 흔하게 쓰이기 때문에 기본으로 설정되었습니다. 물론 Tomcat과 같이 서블릿 기반의 서버들도 쓸 수 있지만, Servlet API를 direct하게 쓰는 것이 아니라, adapter를 거쳐서 쓴다는 특징이 있습니다.

2. 스프링 리액터의 주요 두개 모듈

The spring-web module contains the following foundational support for reactive web applications:

For server request processing there are two levels of support.

HttpHandler: Basic contract for HTTP request handling with non-blocking I/O and Reactive Streams back pressure, along with adapters for Reactor Netty, Undertow, Tomcat, Jetty, and any Servlet 3.1+ container.

WebHandler API: Slightly higher level, general-purpose web API for request handling, on top of which concrete programming models such as annotated controllers and functional endpoints are built.

For the client side, there is a basic ClientHttpConnector contract to perform HTTP requests with non-blocking I/O and Reactive Streams back pressure, along with adapters for Reactor Netty, reactive Jetty HttpClient and Apache HttpComponents. The higher level WebClient used in applications builds on this basic contract.

For client and server, codecs for serialization and deserialization of HTTP request and response content.

HttpHandler는 async, non-blocking I/O 를 위한 HTTP request Handling을 수행한다.

WebHandler는 MVC처럼 controller를 만들고, 요청을 처리하는 API이다.

0개의 댓글