Azure Functions:昂貴對象的單例
我創建了一些非常簡單的 Azure 函式。他們從 Couchbase(在 Azure 中的 VM 上執行)讀取和寫入數據。
我擔心我在 Azure 函式中與 Couchbase 建立的連接。
Cluster我每次都創建一個對象。這是一項昂貴的操作,我通常只會在普通的 Web 應用程序中執行一次。但是在 Azure Function 中,我new每次都在處理它。除了 Couchbase 之外,實例化這樣的對像還有很多昂貴的費用。有沒有辦法創建一個單例,或者 Azure Functions 可以在呼叫之間重用的某種共享對象?
您可以使用普通的單例,即返回某事物的單個實例的靜態屬性。與往常一樣,請注意執行緒安全,例如
Lazy<T>按照@Jesse 的建議使用。您還可以在執行第一次呼叫 Function 之前使用靜態建構子進行初始化。根據定義,靜態建構子是執行緒安全的。
在這兩種情況下,您都可以在同一實例(伺服器)上執行的所有呼叫之間重用昂貴的東西。
在 Azure Functions 上處理單例時,有幾個注意事項。一是全域狀態在 AF 呼叫之間共享。所以,如果一個函式被一次又一次地呼叫(很快主機還沒有解除安裝你的程式碼),那麼初始化只發生一次。另一個考慮因素是 AF 可以完全自由地同時啟動多個 AF 呼叫——因此任何單例都需要是執行緒安全的(包括它們的初始化)。
這意味著您將要使用
Lazy<T>/AsyncLazy<T>。但是,請記住,即使失敗,AF(具有這些類型)也會為您的下一次呼叫保留單例狀態(初始化後) 。這可能是一個問題,尤其是雲計算,因為如果在啟動 AF 時出現網路(或配置)錯誤,您希望在下一次 AF 呼叫時重試初始化。總之,您希望
Lazy<T>/AsyncLazy<T>以一種執行緒安全且不保留故障的方式使用。使用
Lazy<T>,這意味著您必須使用LazyThreadSafetyMode.PublicationOnly標誌 並將函式傳遞給建構子(而不僅僅是隱式使用預設建構子T)。請注意,這意味著您需要確保初始化函式本身是執行緒安全的,因為它可以由多個執行緒同時執行。有了
AsyncLazy<T>,你必須使用AsyncLazyFlags.RetryOnFailure標誌。由於AsyncLazy<T>本質上是 a ,因此非同步初始化任務在所有同時呼叫者之間“共享”,然後如果失敗Lazy<Task<T>>則自動替換為新實例。Lazy<Task<T>所以非同步初始化函式不需要是執行緒安全的。由於一切正常(特別是對於多個單身人士)是相當複制和粘貼,我將其抽像出來用於我正在從事的 AF 項目:
- 首先,我有一個單例抽象,以使同步和非同步單例的構造更簡單、更統一。我的特定實現
AsyncLazy<T>同時用於同步和非同步單例,以便同步初始化函式將“共享”其工作,因此即使多個執行緒同時請求一個實例,它也只會執行一次。- 然後使用這個抽象來創建實際的靜態單例實例,然後在實際呼叫該函式時,我解析當時的實例並將它們註冊到我的 DI 容器(在本例中為 SimpleInjector),同時處理 DI 容器本身作為單身人士。
達到這一點需要一段時間,但我對結果很滿意。也一直想寫部落格…