spring5 reactive 관련
2021, Feb 24
** 2017년 스프링 캠프 발표영상 정리
프로세스와 스레드, NIO 그리고 리액티브 스트림
Thread 일반
- 프로세스
- 프로세스는 프로그램 실행시 code, data, stack, heap의 구조로 되어 있는 독립된 메모리 영역을 할당 받는다.
- 쓰레드 + 메모리 공간 := 프로세스
- OS의 스케줄러에 의해 time slice만큼 실행 (멀티프로세스)
- 쓰레드의 장점
- 위와 같은 멀티 프로세싱 방식은 동작 중인 프로세스가 대기를 타면서 해당 프로세스의 상태(context)를 보관하고 다시 돌아 이전에 보관했던 프로세스의 상태(Context)를 복구하게 된다. 이러한 과정을
Context Switching
이라고 하는데 이 과정은 비용이 많이 드는 작업임. - 쓰레드는 이런 context swiching 없이 프로세스내 힙 메모리 공간을 공유하면서 작동 단위를 별도로 실행 시키므로서 프로세스 하나를 통째로 만드는 것보다 가볍고 빠름.
- 쓰레드 context switching 내부적으로 leve1 ~ leve3의 로컬 캐시를 사용함.
- 쓰레드 풀 : 스레드를 미리 만들어 놓고 재사용하여, 쓰레드 생성 비용을 줄일 수 있음.
- 이런 부분 때문에 멀티 프로세스보다 멀티 스레드가 각광 받게 됨.
- 위와 같은 멀티 프로세싱 방식은 동작 중인 프로세스가 대기를 타면서 해당 프로세스의 상태(context)를 보관하고 다시 돌아 이전에 보관했던 프로세스의 상태(Context)를 복구하게 된다. 이러한 과정을
JVM 내에서의 스레드 비용
- 스레드 생성 비용(OS + JVM) - JVM의 래핑하는 비용 발생
- 멀티스레드도 Context Switching 비용이 있음. (멀티 프로세스 비용보다는 낮지만 비용이 듬)
- Garbage Collection 비용 발생
비동기가 필요한 상황
- CPU expensive
- CPU 자원을 많이 사용하는 코드들 중 분할 가능한 코드는 병렬화 해서 시간 단출
- HDD, Nestwork등 I/O 자원의 실행은 느림.
- I/O 작업을 요청한 스레드는 I/O 작업의 완료를 대기한다. -> 대기하면서 스레드 자원 낭비
- 자바의 비동기 처리
- JVM이 처음 작동을 할 때 main 메소드가 젤 먼저 실행 하게 된다. -> main thread가 됨.
- 쓰레드를 새로 생성하게 되면 새로운 쓰레드가 생성 되는 것.
- 단점
- 실행 흐름을 한눈에 파악하기 어렵다.
- 응답 결과를 알아 볼 수 없다.
- 좀더 추상화된 기술 Future
- Get 메소드를 제공하여, 기존에 wait, notify로 했던 작업을 하나로 추상화 해줬음.
- 단일값만 처리 하기 때문에 복합적으로 구현하기 어렵다.
- 쓰레드 풀에 대해서도 이해가 필요하다.
- 쓰레드풀 내의 스레드가 전체 사용중인 경우 큐에 대기중인 요청들은 처리 시간이 이전 태스크가 끝나야 처리 되기 때문에 응답 시간이 지연 된다.
- CompletableFuture
- 기존 단일 작업 처리를 해결, 콜백 헬을 해결해줌.
- Future, CompletionStage 두개를 구현
- JAVA8에 도입되어 람다 적용 가능
- 스레드간 조합 기능 제공
- 단점을 찾아보자면, 싱글 variable 형태의 콜백 형태임.
- 반복 되는 작업을 Collection에 넣고 이를 CompletableFutre 처럼 처리 할 수 있다면?
NIO
- 스레드풀의 단점
- 스레드풀에 스레드를 너무 많이 생성해 두었다가 사용하지 않으면 메모리 낭비
- fork join을 하지 않는 경우 작업이 일찍 끝나지 않은 쓰레드 때문에 다른 쓰레드가 이미 작업이 끝났어도 대기해야 함.
- nodeJs 처럼 하나의 쓰레드로 논블럭킹 처리하는 개념을 도입하게 됨.
- 1.4, 1.7에 한차례식 도입 됏었음
- New IO
- Native IO
- Nonblocking IO
서블릿에서 논블럭킹 제공
- Servlet 3.0
- AsyncServlet
- Servlet 3.1
- Nonblocking I/O
- Spring MVC
- DefferedResult
Reactive - Event Programming
- 이벤트 발생 -> 처리
- CompletableFuture.complete(“/xxx”)
- thenApply(콜백) <– 결국 이벤트 처리 방식
- Event Programming
- 절차지향 프로그래밍과 비교 되는 이벤트 드리븐 패턴
- 세상은 이벤트 형식으로 돌아가고 있는데 그간 절차형으로 처리 하려고 애쓴건 아닐까?
- JAVA API
- Observable, RxJava, Reactor, Soldium, JDK9 Flow, Vert.x core
- 프레임워크
- Spring5 MVC, AKKA-http, Vert.x Web, Playframework…
- pub/sub 구조에 backpressure 개념 도입.
- backpressure = 배강벨브
- 수도 벨브의 수압을 조절해야 하는 것처럼 응답을 받는 쪽에서 소화할 수 있는 만큼 소비량을 조절할 수 있는 기능