2017-07-27 31 views
1

注意:這是一個設計相關的問題,我無法找到令人滿意的答案。因此在這裏問。實例的連接池和縮放

我有一個部署在雲(Cloud Foundry)中的彈簧啓動應用程序。該應用連接到Oracle數據庫以檢索數據。應用程序使用連接池(HikariCp)來維護與數據庫的連接。假設連接數被設置爲5.現在應用程序可以根據負載自動縮放。所有的實例將共享相同的數據庫。任何時候都可以運行同一應用程序的50個實例,這意味着數據庫連接的總數將是250(即5 * 50)。

現在假設數據庫只能處理100個併發連接。在當前情況下,20個實例將使用可用的100個連接。如果接下來的30個實例嘗試連接到數據庫會發生什麼?如果這是設計問題,那麼如何避免?

請注意,爲簡單起見,問題中提供的數字是假設的。實際數字要高得多。

回答

1

比方說:

  • 提供DB連接數= X
  • 應用程序的併發實例的數目= Y
  • 應用程序的每個實例中的數據庫連接池的最大大小= X/Y

這有點簡單,因爲你可能想連接到你的d來自其他客戶的數據庫(例如支持工具),所以也許一個更安全的公式是(X * 0.95)/Y

現在,您已確保您的應用程序層不會遇到'沒有數據庫連接存在'的問題。但是,如果(X * 0.95)/Y爲25,並且您有超過25個併發請求通過您的應用程序(需要同時連接數據庫),那麼某些請求在嘗試獲取數據庫連接時會遇到延遲,並且如果這些延遲超過配置的超時,他們將導致失敗的請求。

如果你可以限制你的應用程序的吞吐量,這樣你永遠不會有超過(X * 0.95)/Y的併發'獲取數據庫連接'請求,那麼他們就會問題消失。但是,當然,這通常不現實(事實上,因爲更少是更少的......告訴你的客戶停止與你交談通常是一個奇怪的信號發送)​​。這使我們想到問題的癥結所在:

現在應用程序具有根據負載自動縮放的能力。

向上縮放不是免費的。如果在處理100000N併發請求時處理N併發請求時需要相同的響應性,則必須提供;您必須擴大這些請求所需的資源。因此,如果他們使用數據庫連接,那麼數據庫支持的併發連接數將不得不增加。如果服務器端資源不能增長到客戶端使用率,那麼您需要某種形式的背壓,或者需要仔細管理服務器端資源。管理服務器端資源的一種常用方法是...

  • 讓您的服務無阻塞即代表每個客戶端請求的線程池和您的服務中通過回調響應客戶端(春季通過DeferredResult利於這個或它的異步框架或它的RX集成)
  • 配置您的服務器端資源(如您的數據庫允許使用的最大連接數)來匹配您的服務根據您的服務實例的客戶端請求的總規模最大吞吐量的線程池

客戶端請求的線程池的限制每個s中當前活動請求的數量它的服務實例而不是限制客戶可以提交的請求數量。這種方法允許服務向上擴展(達到所有服務實例中由客戶端請求線程池大小表示的限制),並且這樣做允許服務所有者安全地防止資源(例如其數據庫)過載。由於所有客戶端請求都被接受(並委託給客戶端請求線程池),客戶端請求從不被拒絕,所以從他們的角度來看,就好像縮放是無縫的一樣。

這種設計通過負載均衡器進一步增強了服務實例的集羣,這些服務實例通過它們分配流量(循環或甚至通過一些機制,由此每個節點報告它的「忙碌」指導負載平衡器的行爲,例如,將更多的流量引導到NodeA,因爲它被利用不足,因爲它被過度利用而導致較少的到NodeB的流量。

上述對非阻塞服務的描述只是表面劃痕;他們還有很多東西(包括文檔,博客文章,互聯網上有用的比特幣),但考慮到你的問題陳述(面對來自客戶端的負載增加時對服務器端資源的擔憂),這聽起來像是一件好事適合。

+0

這是一個很好的建議。將在此探索更多 – jubin