리액티브 프로그래밍이란?
수년 전까지 대규모 애플리케이션은 수십 대의 서버, 기가바이트의 데이터, 수초의 응답시간, 당연히 여겨졌던 몇 시간의 유지보수 시간 등의 특징을 가졌다.
오늘날에는 다음과 같은 적어도 세 가지 이유로 상황이 변하고 있다.
빅데이터
보통 빅데이터는 페타바이트 단위로 구성되며 매일 증가한다.
다양한 환경
모바일 디바이스에서 수천 개의 멀티 코어 프로세서로 실행되는 클라우드 기반 클러스터에 이르기까지 다양한 환경에 애플리케이션이 배포된다.
사용 패턴
사용자는 1년 내낸 항상 서비스를 이용할 수 있으며 밀리초 단위의 응답 시간을 기대한다.
예전 소프트웨어 아키텍처로는 오늘날의 이런 요구사항을 만족시킬 수 없다.
인터넷 트래픽을 가장 많이 일으키는 디바이스가 모바일인 요즘은 이런 양상이 두드러지고 있으며 사물인터넷(IoT) 같은 기기들로 가까운 미래에는 상황이 더욱 심화될 것이다.
리액트 프로그래밍에서는 다양한 시스템과 소스에서 들어오는 데이터 항목 스트림을 비동기적으로 처리하고 합쳐서 이런 문제를 해결한다.
실제로 이런 패러다임에 맞게 설계된 애플리케이션은 발생한 데이터 항목을 바로 처리함으로 사용자에게 높은 응답성을 제공하고, 다양한 네트워크 상태에서 메시지를 교환하고 전달할 수 있으며, 무거운 작업을 하고 있는 상황에서도 가용성을 제공한다.
리액티브 애플리케이션과 시스템의 발전된 특징은 지금부터 살펴볼 리액티브 매니페스토에 요약되어 있다.
리액티브 매니패스토
리액티브 매니패스토는 리액티브 애플리케이션과 시스템 개발의 핵심 원칙을 공식적으로 정의하고 있다.
반응성(responsive)
리액티브 시스템은 빠를 뿐 아니라 더 중요한 특징으로 일정하고 예상할 수 있느 반응 시간을 제공한다.
결과적으로 사용자가 기대치를 가질 수 있다. 기대치를 통해 사용자의 확신이 증가하면서 사용할 수 있는 애플리케이션이라는 확인을 제공할 수 있다.
회복성(resilient)
장애가 발생해도 시스템은 반응해야 한다.
컴포넌트 실행 복제, 여러 컴포넌트의 시간과 공간 분리, 각 컴포넌트가 비동기적으로 작업을 다른 컴포넌트에 위임하는 등 리액티브 매니페스토는 회복성을 달성할 수 있는 다양한 기법을 제시한다.
탄력성(elastic)
애플리케이션의 새명주기 동안 다양한 작업 부하를 받게 되는데 이 다양한 작업 부하로 애플리케이션의 반응성이 위협받을 수 있다. 리액티브 시스템에서는 무서운 작업 부하가 발생하면 자동으로 관련 컴포넌트에 할당된 자원 수를 늘린다.
메시지 주도(Message-driven)
회복성과 탄력성을 지원하려면 약한 결합, 고립, 위치 투명성 등을 지원할 수 있도록 시스템을 구성하는 컴포넌트의 경계를 명확하게 정의해야 한다.
비동기 메시지를 전달해 컴포넌트끼리 통신이 이루어진다. 이 덕분에 회복성과 탄력성을 얻을 수 있다.
애플리케이션 수준의 리액티브
애플리케이션 수준 컴포넌트의 리액티브 프로그래밍의 주요 기능은 비동기로 작업을 수행할 수 있다는 점이다.
멀티코어 CPU의 사용률을 극대화 하기 위해 리액티브 프레임워크와 라이브러리는 스레드를 퓨처, 액터, 일련의 콜백을 발생시키는 이벤트 루프 등과 공유하고 처리할 이벤트를 변환하고 관리한다.
이들 기술은 스레드보다 가벼울 뿐 아니라 개발자 입장에서는 동시, 비동기 애플리케이션 구현의 추상 수준을 높일 수 있으므로 동기 블록, 경쟁 조건, 데드락 같은 저 수준의 멀티스레드 문제를 직접 처리할 필요가 없어지면서 비즈니스 요구사항을 구현하는데 더 집중할 수 있다.
리액티브 원칙을 따르는 것은 리액티브 프로그래밍의 일부일 뿐이며 가장 어려운 부분은 따로 있다.
리액티브 시스템을 만들려면 훌륭하게 설계된 리액티브 애플리케이션 집합이 서로 잘 조화를 이루게 만들어야 한다.
시스템 수준의 리액티브
리액티브 시스템은 여러 애플리케이션이 한 개의 일관적인, 회복할 수 있는 플랫폼을 구성할 수 있게 해줄 뿐 아니라 이들 애플리케이션 중 하나가 실패해도 전체 시스템은 계속 운영될 수 있도록 도와주는 소프트웨어 아키텍처다.
리액티브 애플리케이션은 비교적 짧은 시간 동안만 유지되는 데이터 스트림에 기반한 연산을 수행하며 보통 이벤트 주도로 분류된다. 반면 리액티브 시스템은 애플리케이션을 조립하고 상호소통을 조절한다.
리액티브 시스템의 주요 속송으로 메시지 주도를 꼽을 수 있다.
리액티브 시스템에서는 수신자와 발신자가 각각 수진 메시지, 발신 메시지와 결합하지 않도록 메시지를 비동기로 처리해야 한다.
각 컴포넌트를 완전히 고립하려면 이들이 결합되지 않도록 해야 하며 그래야만 시스템이 장애와 높은 부하에서도 반응성을 유지할 수 있다. 정확히 말하자면 리액티브 아키텍처에서는 컴포넌트에서 발생한 장애를 고립시킴으로서 장애를 다른 컴포넌트로 전파되서 전체 시스템 장애로 이어지는 것을 막음으로 회복성을 제공한다.
고립과 비결합이 회복성의 핵심이라면 탄력성의 핵심은 위치 투명성이다.
위치 투명성은 리액티브 시스템의 모든 컴포넌트가 수신자 위치에 상관없이 다른 모든 서비스와 통신할 수 있음을 의미한다.
위치 투명성 덕분에 시스템을 복제할 수 있으며 현재 작업 부하에 따라 애플리케이션을 확장할 수 있다.
'Java' 카테고리의 다른 글
[모던 자바] 간단한 리액티브 애플리케이션 만들기 (0) | 2022.03.31 |
---|---|
[모던 자바] 리액티브 스트림과 Flow API란? (0) | 2022.03.30 |
[모던 자바] CompletableFuture를 활용한 비동기 작업 파이프라인 만들기 (0) | 2022.03.29 |
[모던 자바] Future 인터페이스를 활용한 비동기 계산 (0) | 2022.03.29 |
[모던 자바] 디폴트 메서드(default method)란? (0) | 2022.03.18 |