Dot-Net

Azure Functions:昂貴對象的單例

  • September 11, 2017

我創建了一些非常簡單的 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 項目

達到這一點需要一段時間,但我對結果很滿意。也一直想寫部落格…

引用自:https://stackoverflow.com/questions/46162151