java – 了解非阻塞Web服务调用与非阻塞JDBC之间的区别
作者:互联网
我试图从概念上理解为什么在Play Framework 2.0中,为Web服务调用调用WS.url().get()被认为是最佳实践,但是如果你在其中包含任何其他阻塞调用(如JDBC调用)承诺,建议您在默认执行上下文以外的执行上下文中执行此操作?
据我所知,默认情况下,Play Framework的线程池配置为每个核心有一个线程,每个控制器都希望运行完全非阻塞的代码.因此,如果您在控制器(例如,Web服务)中进行阻止调用,那么您需要确保此调用不会阻止可用于控制器的线程.
否则,将不会有任何线程执行控制器,因为它们都处于阻塞状态.
但令我困惑的是以下几点:
>首先,控制器代码本身执行什么线程池?这是默认的执行上下文吗?
>其次,一方面我理解WS.url().get()也在默认执行上下文中执行,但另一方面,Play Framework Documentation on Thread Pool Configuration声明“注意你可能想要…包装你的在期货中阻止代码.这不会使它成为非阻塞,只是意味着阻塞将在不同的线程中发生.“
上面的意思不是说WS.url().get()在同一个默认执行上下文中“只是在不同的线程中发生”吗?在不同的执行上下文中执行JDBC调用有什么不同?
解决方法:
1)播放控制器功能在Play的默认线程池中执行,如链接文档中所述:
Play default thread pool – This is the default thread pool in which all application code in Play Framework is executed. It is an Akka dispatcher, and can be configured by configuring Akka, described below. By default, it has one thread per processor.
因此,您需要非常小心在控制器函数中进行阻塞,因为这会阻塞默认线程池中的线程.
2)播放Web服务是一种非阻塞API,因此它不会阻止它的ExecutionContext.因此,您可以在控制器函数中进行多个WS调用,而不会阻塞默认线程池. WS调用和JDBC调用之间的主要区别在于WS调用在等待来自远程服务器的响应时不会阻塞线程,这些调用是异步调用的. JDBC调用(像大多数java IO一样)会在等待响应时阻塞它的线程.
在不同的ExecutionContext中执行JDBC调用将释放默认的ExecutionContext以执行其他工作,从而允许您的服务器处理更多请求.您可以让Akka为您处理上下文切换的艰苦工作.虽然JDBC调用仍然阻塞了一个线程,但它们至少不会阻塞处理请求的线程.
标签:java,playframework,jdbc,nonblocking 来源: https://codeday.me/bug/20190830/1768774.html