簡體   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