2013-11-27 167 views
0

我使用Netty作爲我的服務器的基礎和MySQL的JDBC。我使用BoneCP來彙集我的JDBC連接。如何檢查I/O操作是阻塞還是非阻塞?

在我的服務器,唯一的I/O操作的JDBC連接。(和PrintWriter的日誌記錄異常到一個文本文件)

我知道,每個JDBC連接使用一個線程。但是,如果我使用BoneCP來彙集連接,它將在某種程度上模擬異步I/O,直到所有連接都被填充。如我錯了請糾正我。

所以我想知道每個給定時間段有多少連接創建(或JDBC執行)會生成阻塞I/O。有什麼方法可以測試我的服務器是否被阻塞?

回答

4

JDBC是一個同步API,意味着調用線程會阻​​止每個操作完成。鑑於一個操作可能需要很長時間(相對來說)才能完成,無論JDBC驅動程序使用阻塞還是非阻塞I/O,從Netty的角度來看,它都應該被視爲阻塞操作。使用連接池不會改變這一點 - 它只是減少了獲取到數據庫連接的開銷。

假設您執行選擇操作,並且該操作需要100毫秒的時間才能完成,因爲它會返回大量數據。如果您在Netty的I/O工作線程上執行該操作,則由該線程管理的所有通道將停止,直到JDBC操作完成。

你如何解決這個問題真的取決於你的應用需求。例如,

  • 測試數據庫是否可以足夠快地響應,以便您可以在I/O工作線程中執行Netty JDBC操作而不會影響客戶端。對於只有少量客戶端連接的輕載服務器來說,這可能是唯一可行的。
  • 取決於您使用的是哪個版本的Netty,可以添加不同的線程池和執行程序模型,您可以將其添加到管道以從I/O線程卸載JDBC操作。
  • 如果您使用的是最新版本的Netty 3(3.6我認爲)或Netty 4,則可以將JDBC操作卸載到完全獨立的線程池,然後在Netty I/O線程上引發自定義事件JDBC操作完成後繼續處理請求。

另一點需要考慮的是,如果數據庫相對較慢,並且服務器處於負載狀態,則需要在允許的連接數上設置一個上限,或者您必須暫停Netty頻道的讀取以使數據庫有機會趕上