自訂 Lambda 函數的 Java 執行時期啟動行為 - AWS Lambda

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

自訂 Lambda 函數的 Java 執行時期啟動行為

此頁面說明 中 Java 函數的特定設定 AWS Lambda。您可以使用這些設定來自訂 Java 執行期啟動行為。這可以減少整體函數延遲並提高整體函數效能,而無需修改任何程式碼。

了解 JAVA_TOOL_OPTIONS 環境變數

在 Java 中,Lambda 支援 JAVA_TOOL_OPTIONS 環境變數,以在 Lambda 中設定其他命令列變數。您可以透過各種方式使用此環境變數,例如自訂分層編譯設定。下一個範例將示範如何針對此使用案例使用 JAVA_TOOL_OPTIONS 環境變數。

範例:自訂分層編譯設定

分層編譯是 Java 虛擬機器 (JVM) 的功能。您可以使用特定的分層編譯設定來充分利用 JVM 的即時 (JIT) 編譯器。通常,C1 編譯器針對快速啟動時間進行了最佳化。C2 編譯器針對最佳整體效能進行了最佳化,但也使用更多記憶體,並且需要更長的時間來達成目標。有 5 個不同等級的分層編譯。在層級 0,JVM 會解譯 Java 位元組程式碼。在層級 4,JVM 會使用 C2 編譯器來分析應用程式啟動期間收集的分析資料。隨著時間的推移,它會監控程式碼使用情況以識別最佳化。

自訂分層編譯層級可協助您調整 Java 函數效能。對於快速執行的小型函數,將分層編譯設定為層級 1 有助於透過讓 JVM 使用 C1 編譯器來改善冷啟動效能。此設定可快速產生最佳化的原生程式碼,但不會產生任何分析資料,也不會使用 C2 編譯器。對於運算密集的較大函數,將分層編譯設定為第 4 級,可最大限度地提高整體效能,而無需支付佈建每個 Lambda 執行環境後第一次調用期間的額外記憶體消耗和額外最佳化工作。

對於 Java 11 執行期及以下版本,Lambda 會使用預設 JVM 分層編譯設定。對於 Java 17 和 Java 21,Lambda 預設會將 JVM 設定為停止層級 1 的分層編譯。從 Java 25 開始,Lambda 預設仍會停止層級 1 的分層編譯,除非在使用 SnapStart 或佈建並行時,在這種情況下會使用預設 JVM 設定。這可改善 SnapStart 和佈建並行的效能,而不會產生冷啟動懲罰,因為分層編譯在這些情況下是在調用路徑之外執行。若要最大化此優點,您可以在 SnapStart 快照之前或預先佈建佈建並行執行環境時,使用 priming - 在函數初始化期間執行程式碼路徑來觸發 JIT。如需詳細資訊,請參閱部落格文章,使用進階入門策略搭配 SnapStart 最佳化 AWS Lambda 的冷啟動效能

自訂分層編譯設定 (主控台)
  1. 開啟 Lambda 主控台中的函數頁面。

  2. 選擇您要自訂分層編譯的 Java 函數。

  3. 選擇組態索引標籤,然後選擇左側選單中的環境變數

  4. 選擇編輯

  5. 選擇 Add environment variable (新增環境變數)。

  6. 針對索引鍵,輸入 JAVA_TOOL_OPTIONS。針對值,輸入 -XX:+TieredCompilation -XX:TieredStopAtLevel=1

    透過 Lambda 主控台新增 JAVA_TOOL_OPTIONS 環境變數
  7. 選擇儲存

注意

您也可以使用 Lambda SnapStart 來解決冷啟動問題。SnapStart 會使用執行環境的快取快照來顯著改善啟動效能。如需有關 SnapStart 功能、限制和支援區域的詳細資訊,請參閱使用 Lambda SnapStart 改善啟動效能

範例:使用 JAVA_TOOL_OPTIONS 自訂 GC 行為

Java 11 執行期使用串行垃圾回收器 (GC) 進行垃圾回收。依預設,Java 17 執行期也會使用串行垃圾回收器。但是,對於 Java 17,您也可以使用 JAVA_TOOL_OPTIONS 環境變數來變更預設垃圾回收器。可以在並行垃圾回收器和 Shenandoah 垃圾回收器之間進行選擇。

例如,如果工作負載使用更多記憶體和多個 CPU,則請考慮使用並行垃圾回收器以獲得更好的效能。可以透過將下列內容附加到 JAVA_TOOL_OPTIONS 環境變數的值來執行此操作:

-XX:+UseParallelGC

如果您的工作負載有許多短期物件,您可以透過啟用 Java 25 中引入的 Shenandoah 垃圾收集器的世代模式,從較低的記憶體耗用中獲益。若要執行此作業,請將下列項目附加至JAVA_TOOL_OPTIONS環境變數的值:

-XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational

Log4Shell 的 Log4j 修補程式 Log4Shell

Java 8、11、17 和 21 的 Lambda 執行時間包含修補程式,可減輕 Log4Shell 漏洞 (CVE-2021-44228),Log4j熱門的 Java 記錄架構。此修補程式會產生冷啟動效能額外負荷。如果您使用的是修補程式版本的 Log4j (2.17.0 版或更新版本),您可以停用此修補程式來改善冷啟動效能。若要停用修補程式,請將AWS_LAMBDA_DISABLE_CVE_2021_44228_PROTECTION環境變數設定為 true

從 Java 25 開始,Lambda 執行時間不再包含 Log4Shell 修補程式。您必須驗證您使用的是 Log4j 2.17.0 版或更新版本。

Ahead-of-Time(AOT) 和 CDS 快取

從 Java 25 開始,Lambda 執行時間包含 Java 執行時間界面用戶端 (RIC) Ahead-of-Time (AOT) 快取,這是一種執行時間元件,可主動輪詢來自 Lambda 執行時間 API 的事件。這可改善冷啟動效能。

AOT 快取專屬於 JVM 組建。當 Lambda 更新受管執行期時,也會更新 RIC 的 AOT 快取。不過,如果您部署自己的 AOT 快取,這些快取可能會失效,或在執行時間更新後導致意外行為。因此,強烈建議在使用受管執行期時不要使用 AOT 快取。若要使用 AOT 快取,您應該使用容器映像部署函數。

AOT 快取無法與類別資料共用 (CDS) 快取搭配使用。如果您在 Lambda 函數中部署 CDS 快取,則 Lambda 會停用 AOT 快取。