Reactive Programming 이것만큼은 알고가자
동기, 비동기, Blocking, Non-Blocking #
동기 #
작업이 순차적으로 진행되며, 한 작업이 완료되기를 기다렸다가 다음 작업을 수행합니다.
비동기 #
작업이 완료될 때 까지 기다리지 않으며 한 작업이 진행되는 동안 다른 작업을 계속 수행합니다.
Blocking #
caller가 callee의 결과에 관심이 있다.
블로킹은 caller가 callee 함수를 호출하면, 호출 대상 함수가 작업을 완료할 때까지 호출자 함수가 블록된다. 즉, 호출자는 다른 작업을 수행하지 못하고 대기한다.
Non-Blocking #
caller가 callee의 결과에 관심이 없다.
논블로킹은 caller가 callee의 함수를 호출하더라도 호출 대상 함수가 작업이 완료되지 않아도 즉시 제어권을 반환한다.
Reactive System의 필수 요소 #
반응성 #
시스템은 사용자 요청 또는 외부 이벤트에 신속하게 응답해야한다. -> 무한한 대기 상태를 피하고, 지연을 최소화하여 사용자 경험을 향상시켜야한다.
탄력성 #
시스템은 변동하는 작업 부하에 대응할 수 있어야 합니다. 이를 통해 자원 사용량을 조절하고 성능을 유지하거나 확장할 수 있다.
내결함성 #
시스템은 하드웨어, 소프트웨어 오류, 장애 또는 부분적 실패에 대한 견고성을 가지고 있어야한다. 즉, 장애가 발생해도 시스템은 게속 동작하거나 빠르게 복구할 수 있어야 한다.
메시지-드리븐 #
Reactive 시스템은 메시지 주도 아키텍처를 사용해 컴포넌트 간 통신을 구현한다. 이벤트 기반 메시지 전달을 통해 느슨하게 연결된 컴포넌트 간 상호작용을 달성할 수 있다.
백 프레셔 #
리액티브 시스템은 데이터 스트림에서 발생하는 작업 부하에 대응하기 위해 백 프레셔 메커니즘을 구현한다.
데이터 생산자와 소비자 간의 조절을 통해 오버플로우를 방지한다.
Reactive Streams #
리액트비 스트림은 비동기적인 데이터 스트림을 처리하기 위한 스펙 및 라이브러리의 일부.
라이브러리 프레임워크 상관없이 데이터 스트림을 비동기로 다룰 수 있는 공통 메커니즘이며, 이 메커니즘을 간편하게 사용할 수 있는 인터페이스 제공
구성
- Publisher
- Subscriber
- Subscription
Publisher #
데이터 스트림을 생성하고 데이터를 발행한다.
데ㅐ이터를 발행하면 Subscriber에게 데이터를 전달한다.
Subscriber #
Subscriber는 데이터 스트림을 소비하고, 발행자로부터 데이터를 수신한다.
데이터를 수신하면 그 데이터를 처리하거나 다른 작업을 수행할 수 있다.
Subscription #
Publisher와 Subscriber 사이의 연결을 나타낸다.
Subscriber는 Subscription을 통해 데이터를 요청하거나 취소할 수 있다.
Subscription 인터페이스를 구현한 클래스는 구독을 관리한다.
리액티브 스트림은 데이터 스트림의 비동기 처리를 간소화하고 대량의 데이터를 효율적으로 처리하기 위해 설계되었다,. 주요 목표 중 하나는 백 프레셔(back-pressure)를 통한 속도 조절과 오버플로우 방지다. 또한, 리액티브 스트림은 다양한 비동기 프로그래밍 환경에서 사용되며, Java의 CompletableFuture, Spring WebFlux, RxJava, Project Reactor 등에서 지원하고 있다.
Java NIO #
Java NIO는 Java IO의 기능을 개선하고, 비동기 논블로킹 입출력을 지원하는 패키지다.
핵심 아이디어는 채널과 버퍼를 사용해 입출력 작업을 효율적으로 처리하는 것이다.
Channel, Buffer #
Java NIO에서 입출력 작업은 채널과 버퍼를 통해 이루어진다.
채널(Channel)은 데이터를 읽고 쓸 수 있는 연결을 나타내며, 파일, 세콧 등 다양한 입출력 소스와 관련될 수 있다.
버퍼(Buffer)는 데이터를 임시로 저장하는 메모리 영역으로, 입출력 작업에 사용된다.
Selector #
셀렉터는 다수의 채널을 모니터링하고, 이벤트 발생 여부를 감지한다.
하나의 스레드에서 여러 개의 채널을 비동기적으로 관리할 수 있도록 도와준다.
이를 통해 다수의 클라이언트 연결 또는 다중 네트워크 소켓을 처리하는 데 유용하다.