Spring Webflux에서 JDBC 호출 차단 실행
저는 PostgreSql을 백엔드 DB로 사용하는 스프링 데이터 jpa와 함께 스프링 웹 플럭스를 사용하고 있습니다.다음과 같이 DB 호출을 하는 동안 메인 스레드를 차단하고 싶지 않습니다.find
그리고.save
동일한 목표를 달성하기 위해, 저는 메인 스케줄러를 가지고 있습니다.Controller
클래스와 ajdbcScheduler
서비스 클래스
제가 정의한 방법은 다음과 같습니다.
@Configuration
@EnableJpaAuditing
public class CommonConfig {
@Value("${spring.datasource.hikari.maximum-pool-size}")
int connectionPoolSize;
@Bean
public Scheduler scheduler() {
return Schedulers.parallel();
}
@Bean
public Scheduler jdbcScheduler() {
return Schedulers.fromExecutor(Executors.newFixedThreadPool(connectionPoolSize));
}
@Bean
public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {
return new TransactionTemplate(transactionManager);
}
}
이제 서비스 계층에서 Get/Save 호출을 수행하는 동안 다음 작업을 수행합니다.
@Override
public Mono<Config> getConfigByKey(String key) {
return Mono.defer(
() -> Mono.justOrEmpty(configRepository.findByKey(key)))
.subscribeOn(jdbcScheduler)
.publishOn(scheduler);
}
@Override
public Flux<Config> getAllConfigsAfterAppVersion(int appVersion) {
return Flux
.fromIterable(configRepository.findAllByMinAppVersionIsGreaterThanEqual(appVersion))
.subscribeOn(jdbcScheduler)
.publishOn(scheduler);
}
@Override
public Flux<Config> addConfigs(List<Config> configList) {
return Flux.fromIterable(configRepository.saveAll(configList))
.subscribeOn(jdbcScheduler)
.publishOn(scheduler);
}
그리고 컨트롤러에서는 다음과 같은 작업을 수행합니다.
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
Mono<ResponseDto<List<Config>>> addConfigs(@Valid @RequestBody List<Config> configs) {
return configService.addConfigs(configs).collectList()
.map(configList -> new ResponseDto<>(HttpStatus.CREATED.value(), configList, null))
.subscribeOn(scheduler);
}
이것이 정확합니까? 또는 더 나은 방법이 있습니까?
제가 이해하는 것은 다음과 같습니다.
.subscribeOn(jdbcScheduler)
.publishOn(scheduler);
태스크가 실행되는 날짜jdbcScheduler
스레드 및 이후 결과는 나의 메인 병렬에 게시될 것입니다.scheduler
이 이해가 맞습니까?
에 대한 당신의 이해는 정확합니다.publishOn
그리고.subscribeOn
(해당 운전자에 대한 원자로 프로젝트의 참조 문서 참조).
특정 스케줄러에서 작동하는 예약 없이 차단 라이브러리를 호출하는 경우 이러한 호출은 사용 가능한 몇 가지 스레드 중 하나(기본적으로 Netty 이벤트 루프)를 차단하고 응용 프로그램은 몇 가지 요청만 동시에 처리할 수 있습니다.
이제 저는 당신이 그렇게 함으로써 무엇을 성취하려고 하는지 확신할 수 없습니다.
먼저 병렬 스케줄러는 CPU 바인딩 작업을 위해 설계되었습니다. 즉, CPU 코어 수만큼(또는 그 이상) 적은 수의 작업을 수행할 수 있습니다.이 경우 스레드 풀 크기를 일반 서블릿 컨테이너의 코어 수로 설정하는 것과 같습니다.앱에서 많은 수의 동시 요청을 처리할 수 없습니다.
(탄력적 스케줄러와 같은) 더 나은 대안을 선택하더라도, 요청 처리가 Spring WebFlux에서 기본적으로 예약되는 Netty 이벤트 루프만큼 좋지 않습니다.
궁극적인 목표가 성능과 확장성인 경우, 반응형 앱에서 차단 호출을 래핑하는 것은 일반 서블릿 컨테이너보다 성능이 저하될 가능성이 높습니다.
대신 Spring MVC와 다음을 사용할 수 있습니다.
- 차단 라이브러리를 처리할 때 JPA와 같은 일반적인 차단 반환 유형 사용
- 사용하다
Mono
그리고.Flux
이러한 라이브러리에 연결되어 있지 않은 경우 유형 반환
이것은 논블로킹은 아니지만 비동기식이므로 복잡성을 처리하지 않고도 더 많은 작업을 동시에 수행할 수 있습니다.
IMHO, 컴퓨터의 리소스를 더 잘 사용하여 이 작업을 실행할 수 있는 방법이 있습니다.설명서에 따라 다른 쓰레드로 통화를 감쌀 수 있으며 이를 통해 실행을 계속할 수 있습니다.
언급URL : https://stackoverflow.com/questions/54864088/execute-blocking-jdbc-call-in-spring-webflux
'IT' 카테고리의 다른 글
정의된 간격으로 Android에서 실행 가능한 스레드를 실행하는 방법은 무엇입니까? (0) | 2023.08.06 |
---|---|
Angular에서 뷰 공급자란 무엇입니까?b/w 제공업체와 view 제공업체의 차이점은 무엇입니까? (0) | 2023.08.01 |
Oracle SQL 개발자 색상 코딩 (0) | 2023.08.01 |
JNI를 통해 Java의 바이트[]를 C의 함수에 전달: jarraybyte 사용 방법 (0) | 2023.08.01 |
$.when.apply($, 일부 어레이)의 역할은 무엇입니까? (0) | 2023.08.01 |