連線池支援

連線池化 LDAP 連線有助於減輕每次 LDAP 互動都建立新 LDAP 連線的額外負荷。雖然存在 Java LDAP 連線池支援,但其組態選項和功能(例如連線驗證和池維護)受到限制。Spring LDAP 針對每個 ContextSource 基礎提供詳細的連線池組態支援。

連線池支援是透過在應用程式內容組態中,提供 <ldap:context-source /> 元素的 <ldap:pooling /> 子元素來提供。「唯讀」和「讀寫」DirContext 物件會分開池化(如果指定 anonymous-read-only)。Jakarta Commons-Pool 用於提供底層的連線池實作。

DirContext 驗證

相較於 JDK 提供的 LDAP 連線池功能,連線池化連線的驗證是使用自訂連線池程式庫的主要動機。驗證允許檢查池化的 DirContext 連線,以確保它們在從連線池取出、放回連線池或在連線池中閒置時,仍然正確連線和組態。

如果組態了連線驗證,則會使用 DefaultDirContextValidator 驗證池化的連線。DefaultDirContextValidator 執行 DirContext.search(String, String, SearchControls),使用空名稱、"objectclass=*" 過濾器,以及設定為限制單一結果的 SearchControls,其中僅包含 objectclass 屬性和 500 毫秒逾時。如果傳回的 NamingEnumeration 具有結果,則 DirContext 通過驗證。如果未傳回任何結果或擲回例外,則 DirContext 驗證失敗。預設設定應適用於大多數 LDAP 伺服器,而無需組態變更,並提供驗證 DirContext 的最快方式。如果您需要自訂,可以使用驗證組態屬性來進行,詳述於 連線池組態

如果連線擲回被視為非暫時性的例外,則連線會自動失效。例如,如果 DirContext 實例擲回 javax.naming.CommunicationException,則會將其解讀為非暫時性錯誤,並且該實例會自動失效,而無需額外的 testOnReturn 操作的額外負荷。被解讀為非暫時性的例外是透過使用 PoolingContextSourcenonTransientExceptions 屬性來組態。

連線池組態

以下屬性可在 <ldap:pooling /> 元素上用於組態 DirContext 連線池

表 1. 連線池組態屬性
屬性 預設值 描述

max-active

8

可同時從此連線池配置的每種類型(唯讀或讀寫)的活動連線數上限。您可以使用非正數表示沒有限制。

max-total

-1

可同時從此連線池配置的活動連線總數上限(適用於所有類型)。您可以使用非正數表示沒有限制。

max-idle

8

每種類型(唯讀或讀寫)的活動連線數上限,這些連線可以保持在連線池中閒置而不會釋放額外的連線。您可以使用非正數表示沒有限制。

min-idle

0

每種類型(唯讀或讀寫)的活動連線數下限,這些連線可以保持在連線池中閒置而不會建立額外的連線。您可以使用零(預設值)來建立零個。

max-wait

-1

連線池在等待傳回連線(當沒有可用連線時)以避免擲回例外狀況的最長毫秒數。您可以使用非正數來無限期等待。

when-exhausted

BLOCK

指定連線池耗盡時的行為。

  • FAIL 選項會在連線池耗盡時擲回 NoSuchElementException

  • BLOCK 選項會等待直到有新物件可用。如果 max-wait 為正數,並且在 max-wait 時間到期後沒有新物件可用,則會擲回 NoSuchElementException

  • GROW 選項會建立並傳回新物件(基本上使 max-active 變得沒有意義)。

test-on-borrow

false

物件是否在從連線池借用之前經過驗證。如果物件驗證失敗,則會從連線池中丟棄,並嘗試借用另一個物件。

test-on-return

false

物件是否在傳回連線池之前經過驗證。

test-while-idle

false

物件是否由閒置物件驅逐器(如果有的話)進行驗證。如果物件驗證失敗,則會從連線池中丟棄。

eviction-run-interval-millis

-1

閒置物件驅逐器執行緒的執行之間休眠的毫秒數。當為非正數時,不會執行閒置物件驅逐器執行緒。

tests-per-eviction-run

3

每次閒置物件驅逐器執行緒執行期間要檢查的物件數量(如果有的話)。

min-evictable-time-millis

1000 * 60 * 30 (30 分鐘)

物件在連線池中閒置的最短時間,超過此時間後,物件才有資格被閒置物件驅逐器驅逐(如果有的話)。

validation-query-base

LdapUtils.emptyName()

驗證連線時要使用的搜尋基準。僅在指定 test-on-borrowtest-on-returntest-while-idle 時使用。

validation-query-filter

objectclass=*

驗證連線時要使用的搜尋過濾器。僅在指定 test-on-borrowtest-on-returntest-while-idle 時使用。

validation-query-search-controls-ref

null;預設搜尋控制設定如上所述。

驗證連線時要使用的 SearchControls 實例的 ID。僅在指定 test-on-borrowtest-on-returntest-while-idle 時使用。

non-transient-exceptions

javax.naming.CommunicationException

以逗號分隔的 Exception 類別清單。列出的例外狀況被視為關於急切失效的非暫時性例外狀況。如果池化的 DirContext 實例的呼叫擲回任何列出的例外狀況(或其子類別),則該物件會自動失效,而無需任何額外的 testOnReturn 操作。

Pool2 組態

以下屬性可在 <ldap:pooling2 /> 元素上用於組態 DirContext 連線池

表 2. 連線池組態屬性
屬性 預設值 描述

max-total

-1

可同時從此連線池配置的活動連線總數上限(適用於所有類型)。您可以使用非正數表示沒有限制。

max-total-per-key

8

連線池配置的物件實例數目上限(已取出或閒置),每個金鑰。當達到限制時,子連線池會耗盡。負值表示沒有限制。

max-idle-per-key

8

每種類型(唯讀或讀寫)的活動連線數上限,這些連線可以保持在連線池中閒置,而不會釋放額外的連線。負值表示沒有限制。

min-idle-per-key

0

每種類型(唯讀或讀寫)的活動連線數下限,這些連線可以保持在連線池中閒置,而不會建立額外的連線。您可以使用零(預設值)來建立零個。

max-wait

-1

連線池在等待傳回連線(當沒有可用連線時)以避免擲回例外狀況的最長毫秒數。您可以使用非正數來無限期等待。

block-when-exhausted

true

是否等待直到有新物件可用。如果 max-wait 為正數,則在 maxWait 時間到期後沒有新物件可用時,會擲回 NoSuchElementException

test-on-create

false

物件是否在借用之前經過驗證。如果物件驗證失敗,則借用會失敗。

test-on-borrow

false

物件是否在從連線池借用之前經過驗證的指示器。如果物件驗證失敗,則會從連線池中丟棄,並嘗試借用另一個物件。

test-on-return

false

物件是否在傳回連線池之前經過驗證的指示器。

test-while-idle

false

物件是否由閒置物件驅逐器(如果有的話)進行驗證的指示器。如果物件驗證失敗,則會從連線池中丟棄。

eviction-run-interval-millis

-1

閒置物件驅逐器執行緒的執行之間休眠的毫秒數。當為非正數時,不會執行閒置物件驅逐器執行緒。

tests-per-eviction-run

3

每次閒置物件驅逐器執行緒執行期間要檢查的物件數量(如果有的話)。

min-evictable-time-millis

1000 * 60 * 30 (30 分鐘)

物件在連線池中閒置的最短時間,超過此時間後,物件才有資格被閒置物件驅逐器驅逐(如果有的話)。

soft-min-evictable-time-millis

-1

物件在連線池中閒置的最短時間,超過此時間後,物件才有資格被閒置物件驅逐器驅逐,但額外條件是每個金鑰至少保留最少數量的物件實例。如果將此設定為正值,則此設定會被 min-evictable-time-millis 覆寫。

eviction-policy-class

org.apache.commons.pool2.impl.DefaultEvictionPolicy

此連線池使用的驅逐策略實作。連線池嘗試使用執行緒內容類別載入器載入類別。如果失敗,連線池會嘗試使用載入此類別的類別載入器載入類別。

fairness

false

連線池公平地服務等待借用連線的執行緒。true 表示服務等待執行緒的方式如同在 FIFO 佇列中等待一樣。

jmx-enable

true

已針對連線池的平台 MBean 伺服器啟用 JMX。

jmx-name-base

null

用作指派給啟用 JMX 的連線池的名稱一部分的 JMX 名稱基準。

jmx-name-prefix

pool

用作指派給啟用 JMX 的連線池的名稱一部分的 JMX 名稱前綴。

lifo

true

連線池是否具有關於閒置物件的 LIFO(後進先出)行為或作為 FIFO(先進先出)佇列的指示器。LIFO 始終從連線池傳回最近使用的物件,而 FIFO 始終傳回閒置物件連線池中最舊的物件

validation-query-base

LdapUtils.emptyPath()

用於驗證搜尋的基準 DN。

validation-query-filter

objectclass=*

用於驗證查詢的過濾器。

validation-query-search-controls-ref

null;預設搜尋控制設定如上所述。

驗證連線時要使用的 SearchControls 實例的 ID。僅在指定 test-on-borrowtest-on-returntest-while-idle 時使用

non-transient-exceptions

javax.naming.CommunicationException

以逗號分隔的 Exception 類別清單。列出的例外狀況被視為關於急切失效的非暫時性例外狀況。如果池化的 DirContext 實例的呼叫擲回任何列出的例外狀況(或其子類別),則該物件會自動失效,而無需任何額外的 testOnReturn 操作。

組態

組態連線池需要新增巢狀於 <ldap:context-source> 元素中的 <ldap:pooling> 元素,如下所示

<beans>
   ...
    <ldap:context-source
        password="secret" url="ldap://localhost:389" username="cn=Manager">
        <ldap:pooling />
    </ldap:context-source>
   ...
</beans>

在真實情況中,您可能會組態連線池選項並啟用連線驗證。先前的範例示範了一般概念。

驗證組態

以下範例在每個 DirContext 傳遞到用戶端應用程式之前對其進行測試,並測試已在連線池中閒置的 DirContext 物件

<beans>
   ...
    <ldap:context-source
        username="cn=Manager" password="secret" url="ldap://localhost:389" >
        <ldap:pooling
            test-on-borrow="true"
            test-while-idle="true" />
    </ldap:context-source>
   ...
</beans>

已知問題

本節描述人們在使用 Spring LDAP 時有時會出現的問題。目前,它涵蓋以下問題

自訂驗證

PoolingContextSource 假設從 ContextSource.getReadOnlyContext() 檢索的所有 DirContext 物件都具有相同的環境,並且同樣地,從 ContextSource.getReadWriteContext() 檢索的所有 DirContext 物件都具有相同的環境。這表示將以 AuthenticationSource 組態的 LdapContextSource 包裝在 PoolingContextSource 中並不能如預期般運作。連線池將會使用第一個使用者的憑證來填充,並且除非需要新的連線,否則後續的內容請求將不會為請求執行緒的 AuthenticationSource 指定的使用者填充。