2016-11-30 19 views
16

我有兩臺安裝了PostgreSQL 9.5數據庫的Linux服務器(AB)。我配置了熱備份模式,如documentation中所述。在此設置中,A被配置爲主設備,B處於熱備份模式。這是行之有效的行爲如預期。如何在JavaEE應用程序中爲PostgreSQL Hot Standby設置配置連接故障轉移?

現在,我想通過TomEE數據源到該數據庫設置通過Hibernate/JDBC連接一個獨立的應用程序Java EE(不同的機器上運行)。

PostgreSQL driver文檔狀態,使多臺主機可以在JDBC連接URL指定:

jdbc:postgresql://host1:port1,host2:port2/database 

所以我的問題是:

  1. 如果A向下,B手動切換到正常操作模式,我的應用程序是否仍然能夠使用上述的jdbc連接url進行數據庫操作?
  2. 我必須配置其他參數/​​庫嗎?

注意:從我學到的各種資源中,PostgreSQL不支持自動故障轉移(除非在此過程中涉及第三方軟件 - 請參閱下面的註釋)。出於這個原因,故障轉移需要手動執行,這對於這個特定的用例來說是可以的。

EDIT-1:

我決定測試pgBouncer(如在意見提出)爲一種解決方法。它適用於我的使用情況。我寫了一個看門狗腳本,它可以自動的手動步驟:

  1. 汽車無校驗,如果A仍然活着,並監聽傳入的連接。
  2. 如果發生故障切換,請將B切換到正常運行模式,並讓它成爲新的主站並重新啓動服務。
  3. pgBouncer設置更改爲指向B而不是A並重新啓動服務。

但是,如果有人有沒有第三方軟件的經驗,我還會感興趣嗎?

+2

最簡單的設置是在兩臺服務器之前放置pgBouncer或pgPool之類的東西,讓應用程序通過它連接。 –

+0

@a_horse_with_no_name感謝您的提示。你現在有沒有什麼有用的指南來設置pgPool(來自Ubuntu倉庫),你會推薦? – rzo

+1

我有一個主和一個只讀熱stanby postgresql 9.6服務器的類似設置。有一個pgbouncer在他們面前運行。我可以通過更改pgbouncer配置文件的一行來輕鬆切換到新的主文件。 我已閱讀有關自動故障轉移羣集(使用corosync和pacemaker)的論文,但對我而言這些文件太複雜。如果您有高級Linux系統管理經驗,您應該嘗試一下。 http://clusterlabs.org/ –

回答

8

在這種情況下,最好測試一下。

我對PostrgeSQL熱備份模式沒有「實際操作」經驗,但是我已經完成了Java應用程序的數據庫故障切換。

首先,測試PostgreSQL driver文檔頁面 關於?targetServerType=master參數(在頁面底部提及)的聲明。
使用通過DriverManager.getConnection使用PostgreSQL JDBC驅動程序的主要方法編寫一個小型Java「PgHsm」類,並運行簡單的更新查詢。
它應該使用服務器A來執行更新查詢。停止服務器A上的PostgreSQL,運行PgHsm:由於服務器B不是主服務器,它應該無法連接。
使服務器B成爲主服務器,運行PgHsm:它應該運行正常。

數據源由TomEE中的數據庫連接池支持。 This page列出了TomEE中可用的那些。 但並非所有的數據庫連接池都相同,我現在更喜歡HikariCP,因爲根據我的經驗,它更可預測地處理「數據庫關閉」情形。 另請參閱在HikariCP的handling database down頁面上測試結果。

不幸的是,HikariCP使用JDBC的get/setNetworkTimeout表現爲 和PostgreSQL JDBC驅動程序does not implement this。 因此,爲了確保(JavaEE)應用程序線程不會永久掛在數據庫操作上,您需要設置connectTimeoutsocketTimeout JDBC驅動程序選項。設置socketTimeout是不穩定的,因爲它會自動爲數據庫的所有查詢設置一個時間限制。

執行的第二個測試涉及更新Java「PgHsm」類,以使用您選擇的數據庫連接池實現 並開始(至少)兩個線程,它們在循環中不斷運行簡單更新查詢(在循環中數據庫連接從池中獲取並在提交/回滾之後返回到池中)。 當您關閉服務器A並將服務器B切換到「主」模式時,監視由「PgHsm」記錄的異常以及線程在執行數據庫操作時等待/掛起的時間。
測試結果可用於更新JDBC驅動程序選項和池設置。注重結果,其中:

  • 無效的連接從池中儘快移除,使得應用程序從池中
  • 儘可能少的應用程序的線程掛起(對於最短的時間量大多是有效的連接)當數據庫發生故障時

第二個測試依賴於服務器A不可用,因此連接測試查詢(由數據庫連接池執行)失敗。 如果兩臺服務器保持可用,但主從交換機連接測試查詢不起作用 並且數據庫連接池將嚮應用程序提供錯誤的(現在只讀的)數據庫連接。 在這種情況下,需要手動干預。 A 「故障切換模式」 爲HikariCP描述here (僅適用於configuration頁中描述的選項allowPoolSuspension):

  • suspendPool()
  • softEvictConnections()
  • 等待,直到activeConnections變爲0 。
  • resumePool()

第三次試驗將與JavaEE應用和現在,你應該有一個良好的IDE一個期望的問題。 應用程序在這些類型的測試之後得到更新以改進處理「數據庫關閉」場景 (例如設置(默認)query-timeouts)並不罕見。 在你的情況下,在手動故障轉移期間使用「暫停,刷新和恢復數據庫連接池」功能(上述模式)也是可取的。

+0

非常深刻的答案! – MWiesner

+0

謝謝您在答案中的詳細解釋。這聽起來像是開始測試我的設置中的行爲的好方法。 – rzo

相關問題