應用程式的快速效能對於提供出色的使用者體驗至關重要!在本文中,我們將探討在無伺服器應用程式中最佳化冷啟動和處理程式效能的陷阱和最佳實踐。
目錄
引言
透過函式即服務(FaaS)實現的無伺服器部署正規化,使開發人員能夠以可伸縮且經濟高效的方式輕鬆部署其應用程式。然而,這種便利性和靈活性也伴隨著一系列需要注意的複雜性。
在早期使用長時間執行伺服器的部署模型中,只要您的伺服器正常執行,您的執行環境就始終可用。這使得您的應用程式能夠立即響應傳入的請求。
新的無伺服器正規化要求我們開發人員尋找方法,以確保您的函式儘快可用並響應請求。
無伺服器函式中的效能陷阱
在無伺服器環境中,您的函式可以縮減到零。這使您能夠將運營成本降至最低,但也會帶來技術成本。當您沒有可用於響應請求的函式例項時,必須例項化一個新的函式。這被稱為冷啟動。
注意:有關冷啟動的詳細解釋以及我們如何在使用 Prisma ORM 時儘可能縮短它們,請閱讀我們最近的文章:我們如何透過 Prisma 將無伺服器冷啟動速度提升 9 倍。
緩慢的冷啟動會導致使用者體驗非常糟糕,並最終降低他們對您產品的使用體驗。這是問題一。
除了冷啟動問題,您的實際處理函式效能也極其重要。無伺服器應用程式通常由許多小型、獨立的函式組成,它們透過 HTTP、事件匯流排、佇列等協議相互互動...
單個函式之間的這種相互通訊在每個請求上建立了一個依賴鏈。如果其中一個函式非常慢,它將影響鏈中的其餘部分。因此,處理程式效能是問題二。
最佳化 FaaS 效能的最佳實踐
在 Prisma,我們花了幾個月的時間深入研究無伺服器環境,並優化了 Prisma 在其中的行為方式。在此過程中,我們發現了許多最佳實踐,您可以在自己的應用程式中採用這些實踐,以儘可能保持高效能。
在本文的其餘部分,我們將介紹我們發現的一些最佳實踐。
將函式託管在與資料庫相同的區域
無論何時您託管需要訪問傳統關係型資料庫的應用程式或函式,您都需要初始化與該資料庫的連線。這需要時間和產生延遲。您執行的任何查詢也是如此。
您的目標是將該時間和延遲降至最低。目前,實現這一目標的最佳方法是確保您的應用程式或函式部署在與您的資料庫伺服器相同的地理區域。
您的請求到達資料庫伺服器的距離越短,連線建立的速度就越快。在部署無伺服器應用程式時,這一點非常重要,因為不這樣做可能導致的負面影響會很顯著。
不這樣做會影響以下所需的時間:
- 完成 TLS 握手
- 建立與資料庫的安全連線
- 執行您的查詢
所有這些因素都在冷啟動期間被啟用,因此都會影響使用 Prisma 資料庫對應用程式冷啟動產生的影響。
在研究這對冷啟動的影響時,我們慚愧地注意到,我們的測試最初幾輪是在 `eu-central-1` 區域的 AWS Lambda 無伺服器函式上進行的,而 RDS PostgreSQL 例項則託管在 `us-east-1` 區域。我們迅速糾正了這個問題,而“之後”的測量結果清楚地顯示了這會對您的資料庫延遲產生巨大影響,無論是在連線建立方面,還是在執行任何查詢方面。

之前

之後
使用與函式距離不盡可能近的資料庫會直接增加冷啟動的持續時間,並且在處理熱請求時,每次執行查詢也會產生相同的開銷。
在處理程式之外執行儘可能多的程式碼
考慮以下無伺服器函式
AWS Lambda 在某些情況下,在函式執行環境的初始啟動期間,會為虛擬環境分配更多的記憶體和 CPU。之後,在您的預熱函式呼叫期間,您的函式可用的記憶體和 CPU 實際上保證是您函式配置中的設定值——這可能比函式外部的資源少。
注意:如果您好奇,這裡有一些資源解釋了上述資源分配差異:
這些知識可用於透過將程式碼移到處理程式範圍之外來提高函式的效能。這確保了在環境擁有更多可用資源時執行處理程式外部的程式碼。
例如,您可能在無伺服器函式中執行類似以下操作:
上面的處理程式函式計算斐波那契數列中的第 40 個數字。計算完成後,您的函式將繼續處理請求並最終返回響應。
將其移到處理程式外部可以使該計算在環境擁有更多可用資源時進行,並且只執行一次而不是每次呼叫都執行。
更新後的程式碼將如下所示:
另一件需要記住的事情是,AWS Lambda 支援頂層 await,這允許您在處理程式之外執行非同步程式碼。
我們發現,在處理程式之外顯式執行 Prisma Client 的 `$connect` 函式對您的函式效能有積極影響
讓您的函式儘可能簡單
無伺服器函式旨在成為非常小、獨立的程式碼片段。如果您的函式的 JavaScript 和依賴樹龐大、複雜或分散在許多檔案中,您會發現執行時讀取和解釋它需要更長的時間。
以下是您可以做的一些事情來提高啟動效能:
- 只包含您的函式實際完成其工作所需的程式碼
- 不要使用會載入許多您不需要的東西的庫和框架
這裡的一般觀點是:需要解釋的程式碼越少,依賴樹越簡單,請求處理得就越快。
避免不必要的工作
函式每次呼叫可能重複使用的任何值計算或開銷大的操作都應作為變數快取到處理程式範圍之外。這樣做可以避免在函式每次呼叫時都執行這些開銷大的操作。
考慮一種情況,從資料庫中獲取一個不經常更改的值,例如可配置的重定向
雖然這段程式碼可以工作,但每次函式呼叫時都會執行查詢重定向的查詢。這並不理想,因為它需要每次都訪問資料庫來查詢您在上次呼叫時已經找到的值。
更好的寫法是首先在處理程式外部檢查是否存在快取值。如果未找到,則執行查詢並將結果儲存以備下次使用
現在,查詢只會在函式首次呼叫時執行。任何後續呼叫都將使用快取值。
預置併發
最後一點需要考慮的是,如果您正在使用 AWS Lambda,可以利用預置併發來保持您的 Lambda 函式處於“熱”狀態。
根據 AWS 文件
注意:預置併發會初始化所需數量的執行環境,使它們準備好立即響應您的函式呼叫。請注意,配置預置併發會產生 AWS 賬戶費用。
這允許您維護指定數量的可用執行環境,這些環境可以在沒有冷啟動的情況下響應請求。
儘管這聽起來很棒,但有幾點重要事項需要牢記:
- 使用預置併發會產生額外費用
- 您的應用程式將永遠不會縮減到 0
這些都是重要的考慮因素,因為增加的成本可能不值得您的特定場景。在採用此措施之前,我們建議您評估它為您的應用程式帶來的價值,並考慮增加的成本是否合理。
總結
在本文中,我們探討了一些我們建議開發人員在使用 Prisma ORM 構建和部署無伺服器函式時的最佳實踐。本文中提到的增強功能和最佳實踐並非詳盡列表。
快速回顧一下,我們建議您:
- 將資料庫託管在離已部署函式儘可能近的地方
- 在處理程式之外執行儘可能多的程式碼
- 儘可能快取可重用值和計算結果
- 讓您的函式儘可能簡單
- 如果您願意權衡財務成本,請考慮使用預置併發
感謝您的閱讀,希望這些資訊對您有所幫助!
不要錯過下一篇文章!
訂閱 Prisma 新聞郵件