리액티브 시스템(Reactive System)이란?
- 어떤 이벤트나 상황이 발생했을 때, 반응을 해서 그에 따라 적절하게 행동하는 것을 의미한다.
- 클라이언트의 요청에 즉각적으로 응답함으로써 지연 시간을 최소화한다.
리액티브 선언문
MEANS: 리액티브 시스템에서 주요 통신 수단으로 무엇을 사용할 것인지 표현한 것입니다.
비동기 메시지 기반의 통신을 통해서 구성요소들 간의 느슨한 결합, 격리성, 위치 투명성 보장
- 위치 투명성: 사용자 및 응용 프로그램이 데이터가 어디에 저장되어 있는지에 대한 세부 정보를 숨긴다.
FORM: 메시지 기반 통신을 통해서 어떠한 형태를 지니는 시스템으로 형성되는지를 나타낸다. (탄력성, 회복성)
- 탄력성(Elastic): 시스템의 작업량이 변화하더라도 일정한 응답을 유지하는 것을 의미한다.
- 응답성을 유지하기 위해서 입력을 처리하기 위한 시스템 자원을 그때 그때 적절하게 추가하거나 감소시킨다.
- 회복성(Resilient): 시스템에 장애가 발생하더라도 응답성을 유지하는 것을 의미한다.
- 회복성을 확보하기 위해서 리액티브 시스템의 구성요소들은 비동기 메시지 기반 통신을 통해 느슨한 결합과 격리성을 보장한다.
→ 시스템 구성 요소들이 독립적으로 분리되기 때문에 장애가 발생 하더라도 시스템은 여전히 응답 가능하고 장애가 발생한 부분만 복구하면 된다는 의미
VALUE: 비동기 메시지 기반 통신을 바탕으로 한 회복성과 예측 가능한 규모 확장 알고리즘을 통해 시스템의 처리량을 자동으로 확장하고 축소하는 탄력성을 확보함으로써 즉각적으로 응답 가능한 시스템 구축 가능
<aside>
시스템 설계 원칙에 따라 대규모 분산 시스템 또는 멀티코어 기반의 클라우드 시스템, 모바일 시스템 등 빠른 응답성을 바탕으로 유지보수와 확장이 용이한 시스템 구축 가능
</aside>
1.3 리액티브 프로그래밍(Reactive Programming)이란?
- 리액티브 프로그래밍은 리액티브 시스템을 구축하는 데 필요한 프로그래밍 모델이다.
- 리액티브 시스템에서 비동기 메시지 통신은 Blocking I/O 방식이 아닌 Non-Blocking I/O 방식의 통신이다.
Blocking I/O 방식의 통신
- 해당 스레드가 작업을 처리할 때까지 남아 있는 작업들은 해당 작업이 끝날때까지 차단되어 대기한다.
Non-Blocking I/O 방식의 통신
- 스레드가 차단되지 않는다.
1.4.1 declarative Programming
- 선언형 프로그래밍으로, C언어나 JAVA 같은 명령형 프로그래밍 방식과 달리 실행할 동작을 구체적으로 명시하지 않고 동작을 하겠다는 목표만 선언한다.
1.4.2 data streams와 the propagation of Change
- data streams는 데이터 흐름, 데이터가 지속적으로 발생한다는 의미이고, the propagation of change는 데이터가 발생할 때마다 이것을 변화하는 이벤트로 보고, 이 이벤트를 발생시키면서 데이터를 계속해서 전달하는 것을 의미한다.
코드로 보는 명령형 프로그래밍 vs 선언형 프로그래밍
// 명령형 프로그래밍 코드 예제
public class Example P
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 3, 21, 10, 8, 11);
int sum = 0;
for(int number : numbers) {
if (number > 6 && (number % 2 != 0)) {
sum += number;
}
}
System.out.println("합계: " + sum);
}
}
- 먼저 for문을 돌아서 numbers에서 각각의 숫자들에 접근하는 동작을 한다.
- 다음으로 if문을 사용해서 6보다 더 큰 숫자이면서, 나머지가 0이 아닌 즉 홀수인 숫자만 선택하기 위한 동작을 진행한다.
- 조건문으로 선택된 숫자들을 sum이라는 변수에 차례차례 더하는 동작을 진행한다.
// 선언형 프로그래밍 코드 예제
public class Example {
public static void main(String[] args){
List<Integer> numbers = Arrays.asList(1, 3, 21, 10, 8, 11);
int sum = numbers.stream()
.filter(number -> number > 6 && (number % 2 != 0))
.mapToInt(number -> number)
.sum();
System.out.println("합계: " + sum);
}
}
- numbers List에 포함된 각각의 숫자에 접근하는 동작을 하는 for문이 사라진 것이다. 구체적인 동작을 Java의 스트림이 내부에서 직접 해준다.
- sum이라는 메서드를 선언만 했지, 구체적인 숫자를 더하는 동작은 스트림 내부에서 대신 처리해준다.
선언형 프로그래밍의 특징
- 선언형 프로그래밍 방식에서는 동작을 구체적으로 명시하지 않고, 목표만 선언한다.
- 각 동작에 대해서 메서드 체인을 형성해서 한문장으로 된 코드를 구성한다.
- 선언형 프로그래밍 방식은 함수형 프로그래밍으로 구성된다.
리액티브 프로그래밍의 구성
Publisher
- 발행인, 발행자 정도로 해석할 수 있다. 발행자, 게시자, 생산자 등 여러가지 용어를 사용하지만, 공통점은
입력으로 들어온 데이터를 제공하는 역할을 한다.
Subscriber
- Publisher가 제공한 데이터를 전달받아서 사용하는 주체이다. 구독자라고 불리고, 데이터를 소비하는 관점에서 소비자라고 불린다.
Data Source
- Publisher의 입력으로 들어온 데이터를 대표하는 용어이다. 리액티브 프로그래밍에서는 Data Stream이라고도 부른다.
Data Source vs Data Stream
Data Source는 원천 데이터로, 측 최초로 생성되는 데이터 그 자체이다. Data Stream은 Publisher의 입력으로 들어오는 데이터의 형태이다. Stream은 ‘연속적으로 흐른다’라는 의미가 있는데, 데이터가 연속적으로 끊임없이 입력으로 들어오는 것을 의미한다.
Operator
- 애플리케이션의 요구사항에 맞게 Publisher와 Subscriber 사이에서 적절한 가공 처리가 이루어지는데, 가공 처리를 담당한다.
- 데이터를 생성하는 Operator부터, 데이터 필터링, 데이터 변환 등 수많은 Operator가 존재한다.
'📗 BOOK > 스프링으로 시작하는 리액티브 프로그래밍' 카테고리의 다른 글
4장 함수형 인터페이스 (1) | 2024.11.20 |
---|---|
3장 Blocking I/O vs Non-Blocking I/O (0) | 2024.11.20 |
2장 리액티브 스트림즈 (1) | 2024.11.20 |