728x90
반응형
속도비교
실제로 얼마나 속도차이가 나는지 blocking 코드와 reactor 코드를 비교해보자.
코드예제
고객에게 쿠폰을 발급하려고 한다.
조건은 가입일 5년 이상, 보유 포인트가 500 이상, 골드 멤버일 경우다.
걸리는 시간은 총 6초이다.
isGoldMember: 골드 멤버인지 확인한다. 3초걸림.
isGreaterThan500point: 보유 포인트 확인. 2초 걸림
checkRegisterPeriod: 등록 기간 체크. 1초걸림.
package com.p8labs.reactive.compareCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Slf4j
@Service
public class CouponService {
public boolean isGoldMember(Member member) throws InterruptedException {
Thread.sleep(3000L);
log.info("CHECK GRADE");
return member.getGrade().equalsIgnoreCase("GOLD");
}
public boolean isGreaterThan500point(Member member) throws InterruptedException {
Thread.sleep(2000L);
log.info("CHECK POINT");
return member.getPoint() >= 500;
}
public boolean checkRegisterPeriod(Member member) {
try {
Thread.sleep(1000L);
log.info("CHECK PERIOD");
LocalDate registerDate = member.getRegisterDttm().toLocalDate();
LocalDate conditionDate = LocalDateTime.now().minusYears(5L).toLocalDate();
return registerDate.isBefore(conditionDate) || registerDate.equals(conditionDate);
} catch (Exception e) {
return false;
}
}
}
Blocking
public boolean blocking(Member member) {
try {
boolean checkRegisterPeriod = couponService.checkRegisterPeriod(member);
boolean isGoldMember = couponService.isGoldMember(member);
boolean isGreaterThan500point = couponService.isGreaterThan500point(member);
return checkRegisterPeriod && isGoldMember && isGreaterThan500point;
} catch (Exception e) {
log.info("ERROR!!!!");
return false;
}
}
결과
총 6초가 걸린다.
CHECK PERIOD
CHECK GRADE
CHECK POINT
걸린시간 6
Mono Blocking
public Mono<Boolean> monoBlocking(Member member) {
// 각 조건을 Flux로 변환하여 비동기 호출
return Mono.zip(
Mono.fromCallable(() -> couponService.checkRegisterPeriod(member)),
Mono.fromCallable(() -> couponService.isGoldMember(member)),
Mono.fromCallable(() -> couponService.isGreaterThan500point(member))
)
.map(tuple -> {
Boolean isRegisterPeriodValid = tuple.getT1();
Boolean isGoldMemberValid = tuple.getT2();
Boolean isGreaterThan500pointValid = tuple.getT3();
// 모든 조건이 참인지 확인
return isRegisterPeriodValid && isGoldMemberValid && isGreaterThan500pointValid;
});
}
결과
리액터 코드로 작성했지만 결과가 blocking 과 동일하다.
이유는 쓰레드가 하나여서 쓰레드가 종료될때까지 기다렸고 그 결과
순차적으로 수행이 되었기 때문이다.
[ Test worker] c.p.reactive.compareCode.CouponService : CHECK PERIOD
[ Test worker] c.p.reactive.compareCode.CouponService : CHECK GRADE
[ Test worker] c.p.reactive.compareCode.CouponService : CHECK POINT
걸린시간 6
Mono 에 Executor 적용하기
@Configuration
public class TaskExecutorConfig {
private static final int TASK_QUEUE_CAPACITY = 100;
private static final int KEEP_ALIVE_SECOND = 60;
private static final String THREAD_NAME_PRFIX = "custom-";
@Bean
public Executor customExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10); // 초기 스레드 수
executor.setMaxPoolSize(50); // 최대 스레드 수
executor.setQueueCapacity(100); // 대기열 크기
executor.setThreadNamePrefix("CustomExecutor-");
executor.initialize();
return executor;
}
}
subscribeOn(Schedulers.fromExecutor(customExecutor)) Executor를 =적용해주었다.
public Mono<Boolean> mono(Member member) {
// 각 조건을 Flux로 변환하여 비동기 호출
return Mono.zip(
Mono.fromCallable(() -> couponService.checkRegisterPeriod(member))
.subscribeOn(Schedulers.fromExecutor(customExecutor)),
Mono.fromCallable(() -> couponService.isGoldMember(member))
.subscribeOn(Schedulers.fromExecutor(customExecutor)),
Mono.fromCallable(() -> couponService.isGreaterThan500point(member))
.subscribeOn(Schedulers.fromExecutor(customExecutor))
)
.map(tuple -> {
Boolean isRegisterPeriodValid = tuple.getT1();
Boolean isGoldMemberValid = tuple.getT2();
Boolean isGreaterThan500pointValid = tuple.getT3();
// 모든 조건이 참인지 확인
return isRegisterPeriodValid && isGoldMemberValid && isGreaterThan500pointValid;
});
}
결과
원하는대로 최대시간 3초가 걸렸다.
customExecutor1,2,3 쓰레드로 각각 함수가 수행이 되었다.
[customExecutor-1] c.p.reactive.compareCode.CouponService : CHECK PERIOD
[customExecutor-3] c.p.reactive.compareCode.CouponService : CHECK POINT
[customExecutor-2] c.p.reactive.compareCode.CouponService : CHECK GRADE
걸린시간 3
결론
블록킹 코드와 비교하여 속도차이를 보았다.
코드도 크게 달라지진 않았다.
중요한 점은 Mono 를 결합하여 쓸때는 반드시 여러개의 쓰레드에서 동작하는지
확인해보자.
728x90
반응형
'Reactive Programing' 카테고리의 다른 글
[Reactive Programming] zipWith (0) | 2024.11.09 |
---|---|
[Reactive Programming] Flux, Mono 개념 (0) | 2024.10.14 |
[Reactive Programming] 개념 (0) | 2024.10.06 |
댓글