原文链接:https:///articles/spring-5-webflux-and-jdbc-to-block-or-not-to-block 作者:Grygoriy Gonchar 译者:developlee 期待良久的Spring5提供了更多对反应式的支持,接下来我们来研究一下如何使JDBC更加异步,以及这么做带来的问题 Spring Framework 5 为函数式响应型编程带来了巨大的进步,你不需要使用ApplicationContext或几十个注释来启动和运行最简单的REST API。Spring 5将提供轻量级Web功能和被动的Web Flux支持,以帮助实现这种转换。这些新特性使得Java和spring 5 更适合构建反应式的web 应用。 为了实现反应式web应用,根据反应式声明 (The Reactive Manifesto)所说,应用必须是响应式,弹性的,可伸缩的,并且是消息驱动的。该列表中的最后一个条件——消息驱动,导致了异步通信方式的大迁移,包括异步RPC和消息传递库、数据库驱动程序等等。关系型数据库(RDBMS)是非常强大和有用的。数据库供应商提供的JVM数据库访问的官方工具是实现JDBC API的驱动程序。但是JDBC被设计成阻塞并且每次数据库的调用都是使用线程的。你无法在API本身的方法或接口中找到能在另一个线程中获得查询结果的接口。 事务的概念并不适用于反应性的世界,因为它是关于阻塞资源的,而这正是你想要避免的。 我部分同意这种观点。然而,这取决于你如何正确使用关系数据库。此外,在高度可伸缩的SQL数据库的新时代(如Amazon的Aurora或谷歌的Cloud Spanner),通过将它们一起使用来实现高吞吐量是合适的。问题是,当我们在一个SQL数据库上构建反应式应用程序时,我们应该做什么? 另一种想法是我从Scala中找到的。我们可以将阻塞调用分发到一个单独的线程池,以避免将阻塞和非阻塞调用混合在一起。这么做允许我们控制线程的总数量,并允许CPU在主执行上下文中提供非阻塞任务,并应用各种优化。 import org.springframework.data.repository.CrudRepository;public interface AddressRepository extends CrudRepositoryAddress, Long> {} 我们可以让它异步执行,并分发给专用的线程池。 @Servicepublic class AddressService { private final AddressRepository repository; private final Scheduler scheduler; public AddressRouter(AddressRepository repository, @Qualifier('jdbcScheduler') Scheduler scheduler) { this.repository = repository; this.scheduler = scheduler; } public Mono<>> findAll() { return async(() -> repository.findAll()); } private 我们的JDBC调度程序应该使用一个专用的线程池来配置,它的大小等于连接的数量。 @Configurationpublic class SchedulerConfiguration { private final Integer connectionPoolSize; public SchedulerConfiguration(@Value('${spring.datasource.maximum-pool-size}') Integer connectionPoolSize) { this.connectionPoolSize = connectionPoolSize; } @Bean public Scheduler jdbcScheduler() { return Schedulers.fromExecutor(Executors.newFixedThreadPool(connectionPoolSize)); }} 然而,这种方法也有困难。主要是事务管理。在JDBC中,事务只能在一个java.sql.Connection中进行。要想在一个事务中进行多个操作,它们必须共享一个连接。如果想在两者之间进行一些运算,则必须让它们保持联系。这么做的话效率不是很高,因为在他们运算的过程中保持了相对数量的闲置连接。 异步JDBC包装器的概念并不新鲜,并且已经在Scala Slick 3库中实现了。最后,非阻塞JDBC可能会出现在Java路线图上。正如它在2016年9月在JavaOne上宣布的那样,我们可能会在Java 10中看到它。 上一篇: 最好的赞赏 就是你的关注 |
|