| 리액티브란? 즉각적으로 변화하는 데이터에 대해 반응하는 프로그래밍 모델.
-> 이 개념은 비동기성과 반응성을 통해 더욱 효율적이고 유연한 애플리케이션을 구축하는 혁신적인 방법 .. 이라고 한다.
위는 리액티브 선언문에 나오는 그림이다.
리액티브는 4가지 설계원칙이 있는하는데
다음과 같다.
In computing, reactive programming is a declarative programming paradigm concerned with data streams and the propagation of change.
변화의 전파와 데이터 흐름과 관련된 선언적 프로그래밍 패러다임이다.
변화의 전파와 데이터 흐름 : 데이터가 변경 될 때마다 이벤트를 발생시켜서 데이터를 계속적으로 전달
선언적 프로그래밍 : 실행할 동작을 구체적으로 명시하는 명령형 프로그래밍과 달리 선언형 프로그래밍은 단순히 목표를 선언
비동기적인 이벤트 처리
리액티브 프로그래밍에서는 이벤트를 비동기적으로 처리하기 때문에, 이벤트가 발생하는 즉시 처리할 수 있습니다. 이는 일반적으로 스레드와 락에 의존하는 전통적인 동기적인 프로그래밍 방식보다 훨씬 효율적이며, 대규모 시스템에서 높은 성능을 보장합니다.
데이터 스트림 처리
리액티브 프로그래밍에서는 데이터 스트림을 다룰 수 있습니다. 이러한 데이터 스트림은 무한하거나 큰 양일 수 있으며, 이벤트가 발생할 때마다 해당 이벤트를 처리하는 콜백 함수를 등록합니다. 이러한 방식은 대규모 데이터 처리에 적합합니다.
반응형 시스템 구현
리액티브 프로그래밍은 반응형 시스템을 구현하는 데 적합합니다. 이는 시스템이 외부 요청에 신속하게 반응하고, 빠른 응답 시간을 제공할 수 있도록 하는 기능입니다.
리액티브 프로그래밍은 옵저버 패턴에 많은 영감을 받았다고 합니다.
옵저버 패턴이란 GoF가 소개한 디자인 패턴 중 하나로
관찰 대상이 되는 객체가 변경되면 대상 객체를 관찰하고 있는 옵저버(Observer)에게 변경사항을 통지(notify) 하는 디자인 패턴을 말합니다.
리액티브 프로그래밍은 옵저버 패턴의 서브젝트와 옵저버의 개념과 유사한 발행자와 구독자를 사용해 데이터를 통지하고 처리합니다. 데이터를 제공하는 측에서 데이터를 소비하는 측으로 통지하는 방식(ex.데이터가 있음을 알리는 방식-지속적으로 확인X)을 일반적으로 푸시 기반 (Push-Based)이라고 부릅니다.
Push 방식 : 데이터의 변화가 발생했을 때 변경이 발행한 곳에서 데이터를 보내주는 방식
<->
Pull 방식 : 변경된 데이터가 있는지 요청을 보내 질의하고 변경된 데이터를 가져오는 방식
[배경]
리액티브 프로그래밍을 구현한 라이브러리들이 정해진 표준없이 구현되기 시작했습니다. 이에 하나의 규칙을 정해서, 여러 리액티브 프로그래밍 구현체들이 상호 변환 가능하도록 만들자는 목소리가 나오기 시작했습니다.
그렇게 만들어진 규칙이 리액티브 스트림즈입니다.
[예시]
리액티브 스트림은 non-blocking(넌블럭킹), backPressure(역압)을 이용하여 리액티브 프로그래밍을 할 때 비동기 데이터 처리의 표준이 되는 스펙입니다.
대표적인 리액티브 스트림즈 표준을 따르는 구현체들은 RxJava, Reactor, Akka 등이 있습니다.
백프레셔는 리액티브 스트림에서 발생하는 데이터 처리 속도 조절과 관련된 문제를 해결하기 위한 메커니즘입니다.
과부하 상태의 컴포넌트에서 치명적인 장애가 발생하거나 제어 없이 처리 중인 메시지를 유실해서는 안 됩니다.
컴포넌트는 장애가 발생해선 안 되기 때문에 상위 컴포넌트에 자신이 과부하 상태라는 것을 알려 부하를 줄이도록 해야 합니다.
데이터 생산자와 소비자 간의 처리 속도 차이로 인해 데이터 처리 과정에서 발생하는 문제를 방지하기 위해 사용됩니다.
[백프레셔에 대한 비유]
현실세계의 화장실에서 우리는 물을 사용하기 위해 수도꼭지를 적정량만 틀어 사용합니다. 물이 적절하게 나와야 우리는 그 물들을 받아 처리(사용)할 수 있습니다. 물이 과도하게 나오면 우리의 처리량이 이를 받쳐주지 못하고 나머지 물은 모두 유실될 것입니다. 소프트웨어 세계에서는 이는 곧 장애입니다. 백프레셔는 이런 수도꼭지같은 역할을 수행합니다.
백프레셔는 주로 pull 방식을 채택합니다. 즉, 소비자가 데이터를 필요로 할 때마다 데이터를 요청하여 가져오는 방식입니다. 이를 통해 소비자가 처리할 수 있는 만큼의 데이터만 가져오면서 문제를 방지할 수 있습니다.
🙋🏻 위에서 리액티브 프로그래밍은 Push 방식이라고 하지 않았나요?
리액티브 스트림은 push 방식을 따릅니다. 즉, 데이터 생산자가 데이터를 생성하고 변경되는 즉시 데이터를 소비자에게 푸시(push)하여 전달하는 방식입니다.
리액티브 프로그래밍과 백프레셔는 서로 다른 측면에서 동작하며, 리액티브 스트림은 비동기 데이터 흐름을 기술하고, 백프레셔는 송신자와 수신자 사이의 데이터 처리 속도 조절에 초점을 둡니다.
Subscriber가 처리하는 속도보다 Publisher가 발행하는 속도가 빠른경우, 대기 중인 데이터가 지속적으로 쌓이면서 오버플로가 발생하거나 최악의 경우에는 시스템이 다운되는 사태가 발생할 수 있습니다.
이러한 문제를 해결하기 위해 백프레셔가 필요합니다.
|
예상. publisher가 subscriber의 처리완료여부를 체크 + 완료된 경우,
새로운 처리를 발생시킴.
리액티브 스트림즈는 4개의 인터페이스인 Publisher(발행자), Subscriber(구독자), Subscription(구독), Processor(프로세서)로 요약이 가능합니다.
발행자(Publisher)는 데이터를 생성하고 통지(발행, 게시, 방출)합니다.
구독자(Subscriber)는 Subscription를 통해 Publisher에게 자신이 처리할 수 있는 만큼의 데이터를 요청하고 처리합니다.
Subscription은 Publisher에 요청할 데이터의 개수를 지정하고 데이터의 구독을 취소하는 역할을 합니다.
Processor 인터페이스는 Subscriber, Publisher 인터페이스를 결합한 것라고 보면 됩니다. 즉 Subscriber로서 다른 Publisher를 구독할 수 있고, Publisher로서 다른 Subscriber가 구독할 수 있습니다.
이때 발행자가 제공할 수 있는 데이터의 양은 무한(unbounded) 하고 오퍼레이션에 따라 순차적(sequential) 처리를 보장합니다.
스프링 프레임워크는 자바를 기반으로 할 경우 리액티브 스트림즈 구현체인 Reactor를 사용