这个激动人心的新项目由Gavin King在上个月宣布;如果您错过了,请查看介绍Hibernate Reactive

Hibernate Reactive

我将重申基本内容,并希望根据我们在Twitter上收到的反馈澄清一些问题。

如您所猜,它提供了一种新的API和实现来连接关系型数据库,而不阻塞或使用线程池。

然而,这个API对Hibernate和JPA用户来说都很熟悉,因此假设响应式编程是您的菜,那么开始使用应该相当直接。开始使用

它依赖于现代、高性能且响应式的Eclipse Vert.x SQL驱动程序;"经典"JDBC驱动程序不适合这个解决方案,因为任何委托给工作池的操作都会使我们的最高效率目标失效。

R2DBC似乎也非常好,但我们必须从某个地方开始!但请放心,虽然我们的团队规模较小,需要一些帮助来集成更多驱动程序,但内部设计并不妨碍我们支持更多非阻塞驱动程序的演变。

Vert.x驱动程序已在Vert.x社区中证明了它们在生产中的表现多年,并在独立基准测试中经常处于非常有竞争力的位置。

由于现在所有与数据库的交互都必须异步运行,这包括延迟加载;解决方案很简单:移除自动(透明)的延迟加载,并引入API来显式获取您需要的数据。

这真是太好了,因为它使得任何加载操作都是显式的,而不是可能意外发生,消除了应用程序意外触碰到"1+N问题"的任何可能性。我个人认为这是一个受欢迎的、相当重要的演变。

版本 1.0.0.Beta2 现已可用;它包括针对与Vert.x驱动程序集成的几个重要改进。

本Hibernate Reactive版本也包含在Quarkus v. 1.11.0.CR1中,今天起也可使用。

线程、上下文和事件循环

我们提升了与高性能Ver.x反应式数据库驱动程序集成的容错性。

显然,这些驱动程序是为Vert.x用户设计的,这意味着它们旨在从事件循环中运行;因此,只要您从Vert.x应用程序中使用Hibernate Reactive,一切都将按设计运行。

但是,如果您要从不同的线程使用Hibernate Reactive,例如那些传统上由其他容器用于处理阻塞操作的线程,您将有自己的应用程序和运行在阻塞线程上的Hibernate会话,但处理查询(语句)结果的下游操作将运行在事件循环中,因为数据库的响应是在事件循环上异步处理的。

正确处理这个问题很棘手,因为它意味着对持久化上下文的数据竞争和并发访问;Hibernate持久化上下文很复杂,不易适应成为线程安全。

不仅使这样的结构线程安全需要大量工作,而且当正确使用时也是不必要的,会导致代码效率更低、更难维护,所以我们没有这样做。

在最新版本1.0.0.Beta2中,Hibernate Reactive API将有效地将工作委托给正确的线程,即使它是错误的线程,因此您不再需要担心这个问题;但我仍然强烈建议您在整个反应式应用程序上运行事件循环,因为这是这些组件被设计时所依据的假设,也是编写高性能、高效反应式应用程序的最有效方式。

所以从技术上讲,这是一个保障,允许偶尔从错误的线程使用,因为在更复杂的混合阻塞和反应式代码的应用程序中,这可能很难预防。

但这并不意味着您应该经常这样做;如果您的应用程序有大量的阻塞代码,可能最好使用传统的Hibernate ORM API和传统的JDBC驱动程序。

在这种情况下,可能更适合使用Project Loom来提高您应用程序的效率,而Hibernate Reactive更适合与其他反应式堆栈结合使用。

限制和保障

我们还没有将相同的技巧应用于Panache Reactive;如果您正在使用Quarkus并尝试使用Panache进行Hibernate Reactive,您真的应该确保您的代码在事件循环上运行。

如果您有疑问,我们可以为您检查。在JVM上设置以下系统属性

org.hibernate.reactive.common.InternalStateAssertions.ENFORCE=true

这将为内部断言启用额外的断言,并在从错误的线程在SQL客户端执行操作时抛出运行时异常。

如果您尝试从阻塞(经典)RESTEasy端点使用Hibernate Reactive与Panache,这很可能会抛出异常;解决方案很简单:将您的端点迁移到使用RESTEasy Reactive。

我正在考虑在将来默认启用一些这样的检查;目前这太具有破坏性了,特别是因为我们还没有完全适应Panache Reactive,但我们正在考虑在未来强制执行这些检查,所以如果您在这面旗子启用的情况下遇到麻烦,请告诉我。

GraalVM原生镜像

由于Hibernate Reactive集成在Quarkus中,不要忘记这意味着您的完全反应式应用程序可以通过GraalVM编译成原生代码!

您可以访问 Hibernate Reactive / Quarkus 快速入门 尝试使用它;然而,我建议您等待 Quarkus 1.11 的最终发布版本,或者将快速入门适配为使用 RESTEasy Reactive;最简单的方法是查看 "开发" 分支,并将 Quarkus 版本(属性 quarkus.platform.version 设置为 1.11.0.CR1),因为它已经被转换了。

我们还没有针对作为原生镜像运行时的速度和内存优化进行工作;任何帮助或反馈都非常欢迎。

反馈、问题、想法?

请尝试使用它,并让我们知道您的看法以及您希望看到哪些改进。欢迎提交补丁。

要联系,请使用常规渠道


返回顶部