Reactive Spring / Reactive Programming

반응형
728x90
반응형

Reactive 의 예시

Reactive의 뜻은 반응형이다. 리액티브를 이해하기 위해서, 하나의 상황을 예로 들어보자.

한 어플리케이션에서 시간당 평균 약 1,000명의 사용자가 방문한다고 가정해보자. 톰캣을 웹 서버로 실행하고, 500개의 스레드로 톰캣 스레드 풀을 구성했다.

위 상황에서, 사용자 요청에 대한 평균 응답 시간은 약 0.250ms이다. 그럼 1초에 2,000명의 사용자의 요청을 처리할 수 있다. 그렇다면 평균 약 1,000명의 사용자가 들어오는 위 어플리케이션의 웹 서버는 평균 부하를 처리하기에 매우 충분하다. 요악하면 이 경우는 처리 능력을 기준으로 애플리케이션을 구성한 것이다. 그런데 만약, 특정 할인날에 폭발적인 고객 증가로 서버 부하가 발생했다고 가정해보자. 스레드 풀에 사용자 요청을 처리할 스레드가 남아있지 않았고, 서비스가 중단되었다.

 

 

어떻게 대응할 것인가?

1) 탄력성 (elasticity) : 더 많은 사용자가 작업을 시작할때 시스템 처리량을 자동으로 증가시키고, 수요가 감소하면 자동으로 감소시킨다.

2) 분산시스템 : 댓글 서비스가 장애가 발생해도, 장바구니나 결제 서비스에는 아무런 영향이 없이 정상적으로 동작해야한다.

3) 탄력성/복원력의 결합 : 확장성을 통해 다수의 복제본을 가질수 있고, 하나의 노드에 장애가 발생할 경우 이를 탐지하고 시스템의 나머지 부분에 미치는 영향을 최소화하며 다른 복제본으로 전환한다.

 

 

메세지 기반 통신

자바에는 병렬 처리를 위해 추가 스레드를 할당할 수 있는 스레드 풀이 있다. 부하가 높은 상태에서 새로운 I/O 작업을 동시에 처리하는건 비효율적일 수 있다. 그런데도 I/O 측면에서 리소스 활용도를 높이려면 '비동기 논블록킹' 모델을 사용해야한다.

 

1) 문자메세지 : 문자메시지를 받으면 응답하는데에 모든 시간이 소모된다. 대답을 기다리지 않고, 그동안 다른 일 (요청을 처리)한다. 업무가 최적화되고 남은 시간을 효율적으로 활용할 수 있다.

분산 시스템에서 서비스 간에 통신할때 자원을 효율적으로 사용하기 위해서는 메세지 기반(message-driven) 통신 원칙을 따라야한다.

 

2) 메세지 브로커 (Message Broker) : 메시지 대기열을 모니터링해 시스템이 부하관리 및 탄력성을 제어할 수 있다.

 

 

콜백지옥 해결

java.util.concurrent.Future

실행동작을 어느정도 숨기고 구성요소도 분리한다. Future는 클래스 래퍼(wrapper)을 사용해 사용 가능한 결과가 있는지를 확인한다. Future을 통해 결과가 비동기적으로 처리되는 동안 다른 처리를 계속할 수 있다. Future 클래스 사용으로 결괏값 반환을 지연시킬 수 있다. 콜백 지옥을 피할수 있다.

 

CaompletionStage<?>

전체적인 동작은 future과 비슷하지만, CompletionStage는 thenAccept, thenCombine과 같은 메소드를 작성할 수 있는 다양한 API를 제공한다. API를 이용해 결과에 대한 변형 연산을 정의하거나 결과를 처리하는 최종 컨슈머를 정의할 수 있는 thenAccept 메서드를 정의할수있다. 결과를 기다리지않고 결과가 나오면 이를 처리할 함수도 제공된다

 

멀티스레딩을 할때에는 여러 스레드에서 공유 메모리에 액세스, 동기화, 오류처리 등과 같은 많은 작업을 생각해야한다.

자바에 있는 멀티스레딩 디자인은 몇몇 스레드가 그들의 작업을 동시에 실행하기 위해 하나의 CPU를 공유할 수 있다고 가정했다. CPU 시간이 여러 스레드 간에 공유된다는 사실을 '컨텍스트 스위칭'이라고 한다. 나중에 스레드를 다시 시작하려면 레지스터, 메모리 맵 및 기타 관련 요소를 저장하고 불러와야한다. 결과적으로 적은 수의 CPU에 동시에 많은 수의 스레드를 활성화시키는 응용 프로그램은 비효율적이다.

 

자바 스레드는 메모리 소비에 오버헤드가 있다. 64비트 JVM에서 스레드의 일반적인 스택 크기는 1,024KB이다. 커넥션마다 별도의 스레드를 할당하는 모델에서 64,000개의 동시 요청을 처리하려는 시도는 약 64GB 메모리가 필요하다. 제한된 크기 스레드 풀을 제공하는 기존 모델로 전환하고 요청에 대해 미리 구성된 대기열을 사용하면 클라이언트가 응답을 받기까지의 대기 시간이 길어지고, 평균 응답 시간이 길어지면서 결국 응용프로그램이 응답하지 않을 수 있다.

 

 

마무리

논블록킹 작업을 사용하도록 권장되어지고 있다. 리액티브 프로그래밍은 하나의 프레임워크가 아닌, 프레임워크에 붙히는 것이다.

 

반응형

'Coding > Spring' 카테고리의 다른 글

SpringBoot 2.4 + Oralce DB 연동하기  (2) 2021.02.04
ResponseEntity에 대해 알아보기  (0) 2020.11.06
필드주입과 생성자주입의 차이  (0) 2019.02.15
싱글톤 레지스트리  (0) 2018.05.08
코드 리팩토링  (0) 2018.05.03

Designed by JB FACTORY