Spring webflux和阻塞与非阻塞JDBC介绍_第1页
Spring webflux和阻塞与非阻塞JDBC介绍_第2页
Spring webflux和阻塞与非阻塞JDBC介绍_第3页
Spring webflux和阻塞与非阻塞JDBC介绍_第4页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Spring webflux和阻塞与非阻塞JDBC介绍 Spring-5-webflux和阻塞与非阻塞JDBC期待良久的Spring5提供了更多对反应式的支持,接下来我们来研究一下如何使JDBC更加异步,以及这么做带来的问题 HYPERLINK https:/spring.io/blog/2017/05/08/spring-framework-5-0-goes-rc1 Spring Framework 5 为函数式响应型编程带来了巨大的进步,你不需要使用ApplicationContext或几十个注释来启动和运行最简单的REST API。Spring 5将提供轻量级Web功能和被动的Web F

2、lux支持,以帮助实现这种转换。这些新特性使得Java和spring 5 更适合构建反应式的web 应用。为了实现反应式web应用,根据反应式声明 (The Reactive Manifesto)所说,应用必须是响应式,弹性的,可伸缩的,并且是消息驱动的。该列表中的最后一个条件消息驱动,导致了异步通信方式的大迁移,包括异步RPC和消息传递库、数据库驱动程序等等。关系型数据库(RDBMS)是非常强大和有用的。数据库供应商提供的JVM数据库访问的官方工具是实现JDBC API的驱动程序。但是JDBC被设计成阻塞并且每次数据库的调用都是使用线程的。你无法在API本身的方法或接口中找到能在另一个线程中

3、获得查询结果的接口。 还有 HYPERLINK https:/spring.io/blog/2017/02/23/spring-framework-5-0-m5-update l comment-3174616521 一种观点认为,事物型数据库不适合反应性概念:事务的概念并不适用于反应性的世界,因为它是关于阻塞资源的,而这正是你想要避免的。我部分同意这种观点。然而,这取决于你如何正确使用关系数据库。此外,在高度可伸缩的SQL数据库的新时代(如Amazon的Aurora或谷歌的Cloud Spanner),通过将它们一起使用来实现高吞吐量是合适的。问题是,当我们在一个SQL数据库上构建反应式应用

4、程序时,我们应该做什么? 一种选择是使用完全非阻塞的替代SQL客户机。比如这里和 HYPERLINK /finagle/roc 这里。 当然,这些驱动程序还没有得到数据库厂商的官方支持。此外,与成熟的基于jdbc的抽象(如Hibernate或jOOQ)相比,功能的吸引力要小得多。另一种想法是我从Scala中找到的。我们可以将阻塞调用分发到一个单独的线程池,以避免将阻塞和非阻塞调用混合在一起。这么做允许我们控制线程的总数量,并允许CPU在主执行上下文中提供非阻塞任务,并应用各种优化。 假设我们有一个基于jdbc的实现,比如Spring Data JPA,它确实是阻塞的。import org.sp

5、ringframework.data.repository.CrudRepository;public interface AddressRepository extends CrudRepository 我们可以让它异步执行,并分发给专用的线程池。Servicepublic class AddressService private final AddressRepository repository; private final Scheduler scheduler;public AddressRouter(AddressRepository repository, Qualifier(j

6、dbcScheduler) Scheduler scheduler)this.repository = repository;this.scheduler = scheduler;public MonoIterable findAll() return async() - repository.findAll();private Mono async(Callable callable) return Mono.fromCallable(callable).publishOn(scheduler);我们的JDBC调度程序应该使用一个专用的线程池来配置,它的大小等于连接的数量。Configura

7、tionpublic class SchedulerConfiguration private final Integer connectionPoolSize;public SchedulerConfiguration(Value($spring.datasource.maximum-pool-size) Integer connectionPoo lSize) this.connectionPoolSize = connectionPoolSize;Beanpublic Scheduler jdbcScheduler() return Schedulers.fromExecutor(Exe

8、cutors.newFixedThreadPool(connectionPoolSize);然而,这种方法也有困难。主要是事务管理。在JDBC中,事务只能在一个java.sql.Connection中进行。要想在一个事务中进行多个操作,它们必须共享一个连接。如果想在两者之间进行一些运算,则必须让它们保持联系。这么做的话效率不是很高,因为在他们运算的过程中保持了相对数量的闲置连接。异步JDBC包装器的概念并不新鲜,并且已经在Scala HYPERLINK / Slick 3库中实现了。最后,非阻塞JDBC可能会出现在Java路线图上。正如它在2016年9月在JavaOne上宣布的 HYPERLI

9、NK /r/programming/comments/54janm/nonblocking_jdbc_api_slides_from_talk_at_javaone/ 那样,我们可能会在Java 10中看到它。Spring Webflux: Kotlin DSL 片断如果您还没有玩转Spring Webflux,那么可以使用基于kotlin的DSL开发一个函数式API。Spring Webflux最近 HYPERLINK https:/spring.io/blog/2017/01/04/introducing-kotlin-support-in-spring-framework-5-0 介绍一

10、个特性来定义函数式API,它使用一个非常直观的基于 HYPERLINK / Kotlin的 HYPERLINK /docs/reference/type-safe-builders.html DSL。这篇文章将简单地展示一组具有鲜明对比的定义API的方式,一个是基于java流畅的API,一个是基于Kotlin的DSL。在Java中,使用函数式编程风格来定义一组CRUD的Spring Webflux API,代码通常是这样的:RouterFunction apis() return nest(path(/hotels), nest(accept(MediaType.APPLICATION_JSO

11、N), route(GET(/), messageHandler:getMessages).andRoute(POST(/), messageHandler:addMessage).andRoute(GET(/id), messageHandler:getMessage).andRoute(PUT(/id), messageHandler:updateMessage).andRoute(DELETE(/id), messageHandler:deleteMessage);这些API的细节非常清楚,并且以一种流畅的方式定义,只有几个关键字route、nest和HTTP行为。这些API也可以使用基

12、于kotlin的DSL(以及一些巧妙地使用Kotlin扩展函数),用下面的方式来实现:Beanfun apis() = router (accept(APPLICATION_JSON) and /messages).nest GET(/, messageHandler:getMessages) POST(/, messageHandler:addMessage) GET(/id, messageHandler:getMessage) PUT(/id, messageHandler:updateMessage) DELETE(/id, messageHandler:deleteMessage) HYPERLINK /mixitconf/mixit/blob/master/src/main/kotlin/mixit/web/routes/ApiRoutes.kt 我觉得这比基于java的DSL在可读性方面要好一些。如果这个API更加复杂,譬如Sbastien Deleuze所演示的精彩例子中所示,有

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论