繁体   English   中英

了解非阻止Web服务调用与非阻止JDBC之间的区别

[英]Understanding the Difference Between Non-Blocking Web Service Calls vs Non-Blocking JDBC

我试图从概念上理解为什么在Play Framework 2.0中,为Web服务调用调用WS.url().get()被认为是最佳实践,但是如果你在其中包含任何其他阻塞调用(如JDBC调用)承诺,建议您在默认执行上下文以外的执行上下文中执行此操作?

据我所知,默认情况下,Play Framework的线程池配置为每个核心有一个线程,每个控制器都希望运行完全非阻塞的代码。 因此,如果您在控制器(例如,Web服务)中进行阻止调用,那么您需要确保此调用不会阻止可用于控制器的线程。

否则,将不会有任何线程执行控制器,因为它们都处于阻塞状态。

但令我困惑的是以下几点:

  • 首先,控制器代码本身执行什么线程池? 这是默认的执行上下文吗?
  • 其次,一方面我理解WS.url().get()也在默认执行上下文中执行,另一方面, 线程池配置上Play Framework文档指出“请注意,你可能会想要...将你的阻止代码包装在Futures中。这不会使它成为非阻塞,只是意味着阻塞将在不同的线程中发生。“

上面的意思不是说WS.url().get()在同一个默认执行上下文中“只是在不同的线程中发生”吗? 在不同的执行上下文中执行JDBC调用有什么不同?

1)播放控制器功能在Play的默认线程池中执行,如链接文档中所述:

播放默认线程池 - 这是默认线程池,其中执行Play Framework中的所有应用程序代码。 它是Akka调度程序,可以通过配置Akka进行配置,如下所述。 默认情况下,每个处理器有一个线程。

因此,您需要非常小心在控制器函数中进行阻塞,因为这会阻塞默认线程池中的线程。

2)播放Web服务是一种非阻塞API,因此它不会阻止它的ExecutionContext 因此,您可以在控制器函数中进行多个WS调用,而不会阻塞默认线程池。 WS调用和JDBC调用之间的主要区别在于WS调用在等待来自远程服务器的响应时不会阻塞线程,这些调用是异步调用的。 JDBC调用(像大多数java IO一样)会在等待响应时阻塞它的线程。

在不同的ExecutionContext执行JDBC调用将释放默认的ExecutionContext以执行其他工作,从而允许您的服务器处理更多请求。 您可以让Akka为您处理上下文切换的艰苦工作。 虽然JDBC调用仍然阻塞了一个线程,但它们至少不会阻塞处理请求的线程。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM