使用 R2DBC 的动机是什么?
What is the motivation for using R2DBC?
我对反应式 spring 堆栈非常陌生,目前正在探索 R2DBC
。
你能解释一下使用 R2dbcRepository
比将阻塞 JpaRepository
包装到 Mono
/Flux
有什么好处吗?
让我举几个例子:
val producer: Mono<BookEntity> = booksReactiveRepository.findById(id)
对
val producer: Mono<BookEntity> = Mono.fromSupplier { booksBlockingRepository.findById(id) }
执行上有概念上的区别吗?
主要区别在于 JDBC/JPA 使用阻塞 I/O 这意味着每个请求都需要一个专用线程。在高并发系统中,这很容易导致扩展问题。
另一方面,R2DBC 使用非阻塞 I/O,这意味着它能够仅使用固定的、少量的线程来处理请求,这使得扩展更容易且成本更低。
查看以下文章:
https://spring.io/blog/2018/12/07/reactive-programming-and-relational-databases
Java uses JDBC as the primary technology to integrate with relational
databases. JDBC is of a blocking nature – there’s nothing sensible one
could do to mitigate the blocking nature of JDBC. The first idea for
how to make calls non-blocking is offloading JDBC calls to an Executor
(typically Thread pool). While this approach somewhat works, it comes
with several drawbacks that neglect the benefits of a reactive
programming model.
Thread pools require – no surprise – threads to run. Reactive runtimes
typically use a limited number of threads that match the number of CPU
cores. Additional threads introduce overhead and reduce the effect of
thread limiting. Additionally, JDBC calls typically pile up in a
queue, and once the threads are saturated with requests, the pool will
block again. So, JDBC is right now not an option.
我对反应式 spring 堆栈非常陌生,目前正在探索 R2DBC
。
你能解释一下使用 R2dbcRepository
比将阻塞 JpaRepository
包装到 Mono
/Flux
有什么好处吗?
让我举几个例子:
val producer: Mono<BookEntity> = booksReactiveRepository.findById(id)
对
val producer: Mono<BookEntity> = Mono.fromSupplier { booksBlockingRepository.findById(id) }
执行上有概念上的区别吗?
主要区别在于 JDBC/JPA 使用阻塞 I/O 这意味着每个请求都需要一个专用线程。在高并发系统中,这很容易导致扩展问题。
另一方面,R2DBC 使用非阻塞 I/O,这意味着它能够仅使用固定的、少量的线程来处理请求,这使得扩展更容易且成本更低。
查看以下文章: https://spring.io/blog/2018/12/07/reactive-programming-and-relational-databases
Java uses JDBC as the primary technology to integrate with relational databases. JDBC is of a blocking nature – there’s nothing sensible one could do to mitigate the blocking nature of JDBC. The first idea for how to make calls non-blocking is offloading JDBC calls to an Executor (typically Thread pool). While this approach somewhat works, it comes with several drawbacks that neglect the benefits of a reactive programming model.
Thread pools require – no surprise – threads to run. Reactive runtimes typically use a limited number of threads that match the number of CPU cores. Additional threads introduce overhead and reduce the effect of thread limiting. Additionally, JDBC calls typically pile up in a queue, and once the threads are saturated with requests, the pool will block again. So, JDBC is right now not an option.