Spring Webflux
1 Spring Webflux
1.1 용도
- 비동기 논블록킹 리액티브 개발에 사용
- 효율적으로 동작하는 고성능 웹 애플리케이션 개발
- 서비스간 호출이 많은 마이크로서비스 아키텍처에 적합
1.2 비동기 논블록킹 리액티브 개발
- 비동기 논블록킹 리액티브 웹 애플리케이션을 개발하려면
- WebFlux + 리액티브 리포지토리, 리액티브 원격 API 호출, 리액티브 지원 외부 서비스, @Async 블록킹 IO
- 코드에서 블록킹 작업이 발생하지 않도록 Flux 스트림 또는 Mono에 데이터 넣어서 전달
2 동기 비동기
2.1 동기
- 동기란 A와 B가 시작시간 또는 종료시간이 일치하는 것을 의미한다
동기에 다양한 예시
- A, B 쓰레드가 동시에 작업을 시작하면 동기
- CyclicBarrier
- A(메소드 리턴시간), B(결과를 전달받는 시간)이 일치하면 동기
- A끝나는 시간과 B가 시작하는 시간이 같으면 동기
- synchronized
- BlockingQueue
2.2 비동기
2.3 블록킹 논블록킹
- 동기, 비동기와는 관점이 다르다
- 내가 직접 제어할 수 없는 대상을 상대하는 방법이다
- 대상이 제한적이다
- IO
- 멀티쓰레드 동기화
3 @Async
3.1 @Async 메서드가 지원하는 반환 타입
- void
Future<T>
ListenableFuture<T>
CompletableFuture<T>
3.2 주의사항
- @Async가 붙은 메서드를 호출할 때 마다 새로운 쓰레드를 만들고 버린다
- 쓰레드 풀을 사용하는 것이 아니기 때문에 일회용 쓰레드를 만들어 쓰는것은 상당한 낭비
- @Async를 본격적으로 사용한다면 쓰레드 풀을 지정해서 사용하자
Mono
Flux
프로그래밍으로 아이템 Emitting
- 코드를 짜서 퍼블리셔 쉽게 만들기
create 메서드
- generate 메서드와 비교하면 더 로우 레벨 직접 반복문을 제어한다
generate 메서드
- create 메서드와 비교하면 더 하이 레벨 직접 반복문을 제어하지 않는다
- synchronousSink 사용
- generate 메서드 안에서 오직 한번만 next 메서드를 호출한다
- 반복을 종료하고 싶다면 반본 종료 조건이 만족될 때 complete 메서드를 호출하자
Flux.generate(sysnchronousSink -> {
String country = Util.faker().country().name();
System.out.println("Emitting : " + country);
sysnchronousSink.next(country);
if (country.toLowerCase().equals("india")) {
sysnchronousSink.complete();
}
}).subscribe(Util.subscriber());
// complete if country is india
// complete if the couter is > 10
Flux.generate(() -> 1, (counter, synchronousSink) -> {
String country = Util.faker().country().name();
synchronousSink.next(country);
if (country.toLowerCase().equals("india") || counter >= 10) {
synchronousSink.complete();
}
return counter + 1;
}).subscribe(Util.subscriber());