회사에서 webflux를 사용해보면서 이것이 정확히 어떤것인지 리액티브는 뭐고 어떤것인지 모르는 상태로 작업을 했다. webflux 그리고 webclient를 정확하게 이해하기 위해서 공부를 막 시작하는 단계라 내용에 오류가 있을 수도 있지만 정리를 해본다.
리액티브 시스템이란
하드웨어가 발전하고 인터넷이 발전함에 따라 하루에 수많은 데이터가 움직이고 계산되며 데이터를 다루는 시스템들은 점점 규모가 커지고있다. 수십대의 서버를 사용하고 응답대기시간이 긴 시스템들을 유지보수하려면 몇시간 혹은 몇일이 걸리는 작업이 될 수도 있다. 또한 이러한 긴 응답시간들은 사용자들의 빠른 응답 요구를 수용하지 못한다. 이러한 이유로 그만한 효율을 내기 위해 **리액티브**라는 **설계 원칙**이 제시되었다.
리액티브 특징
- 응답성: 시스템이 가능한 즉각적으로 응답해야한다.
- 탄력성: 시스템 장애가 발생하여도 응답성을 유지한다.
- 유연성: 시스템이 작업량이 변화하더라도 응답성을 유지한다.
- 메시지 구동: 비동기 메시지 전달에 의존하여 구성 요소사이에 느슨한 결합, 격리, 위치 투명성을 보장한다.
리액티브는 사전적 의미인 반응의 의미를 그대로 가지고 있다. 사용자가 UI 등을 입력하면 신속하게 응답을 하기도 하고, 데이터 상태가 변경되면 그것을 사용하고 있는 시스템에서 해당 내용에 대해 즉각 반응하는 것이다.
애플리케이션 수준
애플리케이션은 프로그래밍 기능을 비동기로 수행이 가능하다. 기존의 동시성 방식은 많은 쓰레드를 사용하게 된다. 어떤 것을 요청해두고 작업을 이어나가기 위해 다른 쓰레드에 작업을 할당하고 필요할때마다 쓰레드를 늘려나가면서 요즘같이 대량의 요청을 처리하는 시스템에서는 쓰레드 점유율이 높아 성능이 낮아지게된다.
리액티브는 쓰레드를 퓨처, 액터, 콜백을 발생시키는 이벤트 루프등과 공유하고 처리할 이벤트를 변환하고 관리한다. 또한 별도로 지정된 스레드 풀에서 블록 동작을 실행시켜 스레드 블록 문제를 해결한다.
시스템 수준
리액티브 시스템은 각 애플리케이션이 독립적인 구조를 가지며 장애 전파가 안되고 쉽게 회복이 가능한 구조를 가지게 된다. 메시지 주도(message-driven)이 사용된다.
리액티브 시스템은 송신자(Pub)와 수신자(Sub)가 강하게 결합하지 않고 독립적인 구조를 유지하도록 메시지를 비동기로 처리한다.
시스템 장애가 발생했을 때 문제를 고립시켜 시스템을 복구한다. 에러 전파를 방지하고 메시지 방향을 바꾼다. 이로 컴포넌트 문제는 그 자체로 한정시킬 수가 있다.
또한 리액티브 시스템은 모든 컴포넌트가 다른 서비스와 통신을 사용할 수 있고 위치에 상관없이 작동하기 때문에 시스템을 복제할 수 있다.
리액티브 프로그래밍
리액티브 프로그래밍은 리엑티브 시스템의 하위 항목으로 보면 된다. 리액티브 프로그래밍은 프로그래밍의 패러다임이다. 객체 지향 프로그래밍, 함수형 프로그래밍 등과 같이 생각하면 된다. non-blocking이며 backpressure를 전제해 처리한다.
역압력(backpressure): Producer의 데이터 생산이 Consumer보다 빠르다면 부하가 발생할 수가 있다. backpressure는 이를 방지하는 것을 말한다. consumer가 느리고 publisher가 빠를때 pull처럼 동작하여 요청 수를 조절하게된다.
그러면 리액티브 프로그래밍은 어떠한 특징을 가지고 있는지 기존의 명령형 프로그래밍과 비교를 해보자면 다음과 같다.
- 명령형 프로그래밍
- 코드가 정해진 순서대로 실행된다.
- PULL 방식 - 구독객체가 주제객체에게 상태를 요청하는 방식
- 리액티브 프로그래밍
- 데이터 흐름이 정의되고 데이터가 변경되 었을 때 함수나 수식이 업데이트되는 방식
- PUSH 방식 - 주제객체가 구독객체에게 상태를 보내는 방식 (backpressure를 사용한다면 이 방법은 소비효율에 따라 pull방식으로 조절될 수 있다)
이와 같은 특징으로 보면 리액티브는 프로그램이 주도하는 방식이 아닌 주변의 환경이 변하면 그에 맞는 상호작용이 일어나는 방식이다.
스프링 webflux에서 사용하는 Reactor는 Reactive Streams 표준 스펙을 따른다. webflux는 추후 포스팅에서 설명하겠다.
참고
[리액티브 스트림으로의 여행 글 요약 :: 자바캔(Java Can Do IT) (tistory.com)](https://javacan.tistory.com/entry/a-journey-into-reactive-streams-summary)
[Spring Webflux + Reactor :: Dreamchaser's Note (tistory.com)](https://dreamchaser3.tistory.com/6)
[Reactive Programming 101 : 리액티브 프로그래밍이 뭔가요 | juneyr.dev](https://juneyr.dev/reactive-programming)
[Backpressure in Reactive Systems (frankel.ch)](https://blog.frankel.ch/backpressure-reactive-systems/)
'웹 개발' 카테고리의 다른 글
테이블 파티셔닝 (0) | 2021.04.11 |
---|---|
오라클 아키텍처(Oracle Architecture) (0) | 2021.04.07 |
블로킹(Blocking)과 논블로킹(NonBlocking) 그리고 동기(Synchronous)와 비동기(Asynchronous) (0) | 2021.03.27 |
서블릿(Servlet) (0) | 2021.03.26 |
[Apache MPM] Prefork, Worker, Event (0) | 2021.03.25 |