Spring Cloud Function Native Images (Spring Cloud Function 原生映像檔)

Engineering (工程) | Dave Syer | May 04, 2020 (2020年5月4日) | ...

Here's the latest graph of memory versus billing for Spring Cloud Function on AWS Lambda. It shows the billing metric GBsec as a function of memory allocation in Lambda for two custom runtimes, one in plain Java and one using a GraalVM native image, as described recently in this blog by Andy Clement (這是 Spring Cloud Function 在 AWS Lambda 上的記憶體與計費的最新圖表。它顯示了計費指標 GBsec 作為 Lambda 中記憶體分配的函數,適用於兩種自定義運行時,一種使用純 Java,另一種使用 GraalVM 原生映像檔,正如 Andy Clement 最近在這篇部落格中描述的那樣)

aws-billing-3.x

In both cases the functionality is identical (a simple POJO-POJO function), and they both show only the results for cold start. Warm starts, where the function was already active when the request came in, were much faster and cheaper (except for the smallest memory setting they all cost the same because there is a minimum charge for all functions in AWS). You can see that the native images start up very fast and that they are more than two times cheaper to run than the regular JVM. The fastest startup was in the 1000MB container - it only took 19ms to start the app, but it took AWS 700ms to prepare the container, so it was billed at 800ms. In fact, all of the cold starts were billed at 800ms for the native image. For the regular JVM the fastest startup was also in the 1000MB container at 300ms, but it was billed at 2200ms. (在這兩種情況下,功能都是相同的(一個簡單的 POJO-POJO 函數),它們都只顯示冷啟動的結果。熱啟動,即當請求到達時函數已經處於活動狀態,速度更快且成本更低(除了最小的記憶體設置,它們的成本都相同,因為 AWS 中所有函數都有最低費用)。您可以看到原生映像檔啟動速度非常快,而且運行成本比常規 JVM 便宜兩倍以上。最快的啟動是在 1000MB 的容器中 - 啟動應用程式僅需 19 毫秒,但 AWS 需要 700 毫秒來準備容器,因此計費為 800 毫秒。實際上,所有冷啟動的原生映像檔都被計費為 800 毫秒。對於常規 JVM,最快的啟動也在 1000MB 的容器中,為 300 毫秒,但計費為 2200 毫秒。)

For comparison, here's the a similar graph that I published over a year ago when Spring Cloud Function reached its 2.0 release. It showed significant improvements over the 1.x version, and also featured the custom runtime which I am using again here (so the orange bars are the equivalent of the red bars in the graph above) (為了比較,這是我在一年前 Spring Cloud Function 達到 2.0 版本時發布的類似圖表。它顯示了比 1.x 版本顯著的改進,並且還具有我再次在此處使用的自定義運行時(因此橙色條與上圖中的紅色條等效))

aws-billing

The custom runtime in the regular JVM is roughly the same in version 3.x, but you can use it at lower memory settings because of Spring Boot optimizations that have been released since then. (常規 JVM 中的自定義運行時在 3.x 版本中大致相同,但由於自那以後發布的 Spring Boot 優化,您可以在較低的記憶體設置下使用它。)

Building the Sample (建立範例)

The sample app was taken from the Spring Graal Native Feature, but modified to be a function of POJO to POJO, forcing Spring to do some extra work. So compared to the sample in Github I modified the function (此範例應用程式取自 Spring Graal Native Feature,但已修改為 POJO 到 POJO 的函數,迫使 Spring 執行一些額外的工作。因此,與 Github 中的範例相比,我修改了該函數)

class Foobar implements Function<Foo, Foo> {

	@Override
	public Foo apply(Foo input) {
		System.err.println("HI: " + input.getName());
		return new Foo("hi " + input.getName() + "!");
	}
}

where the Foo is defined like this (其中 Foo 的定義如下)

class Foo {
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Foo(String name) {
		this.name = name;
	}

	Foo() {
	}
}

and the function is registered in the main application (並且該函數已在主應用程式中註冊)

	@Override
	public void initialize(GenericApplicationContext context) {
		context.registerBean("foobar", FunctionRegistration.class,
				() -> new FunctionRegistration<>(new Foobar())
						.type(FunctionType.from(Foo.class).to(Foo.class)));
	}

Note that I am using the functional bean registration style, although it doesn't make much difference for such a simple application. (請注意,我正在使用 函數式 bean 註冊樣式,儘管對於如此簡單的應用程式來說,它並沒有太大的區別。)

I also had to modify the tests to make sure they work with the new POJO signature. You could just delete the tests and the verify.sh to avoid having to do that, if you just want something quick to work. If you want to see what I did look at the foo branch in my fork. (我還必須修改測試,以確保它們適用於新的 POJO 簽章。如果您只想快速工作,您可以直接刪除測試和 verify.sh 以避免這樣做。如果您想查看我做了什麼,請查看我的 fork 中的 foo branch。)

Then I built the application in the same way as the other samples. This creates the native image and dumps it in the target directory (然後我以與其他範例相同的方式建立了應用程式。這會建立原生映像檔並將其轉儲到 target 目錄中)

$ ./build.sh

It also creates a .zip file to upload to AWS. This one is the regular JVM version (它還會建立一個 .zip 檔案以上傳到 AWS。這個是常規 JVM 版本)

$ ls -l target/*.zip
-rw-rw-r-- 1 dsyer dsyer 32577121 Apr 21 09:37 target/function-aws-0.0.1-SNAPSHOT-java-zip.zip

and then this creates a .zip file for the native image (然後這會建立一個 .zip 檔案,用於原生映像檔)

$ ./mvnw package -P native
$ ls -l target/*.zip
-rw-rw-r-- 1 dsyer dsyer 32577121 Apr 21 09:37 target/function-aws-0.0.1-SNAPSHOT-java-zip.zip
-rw-rw-r-- 1 dsyer dsyer 26284838 Apr 21 09:28 target/function-aws-0.0.1-SNAPSHOT-native-zip.zip

Conclusion (結論)

Using Spring Cloud Function is a very convenient way to develop functions that run on AWS and other platforms. If you also use the experimental Spring Graal Native Feature project to compile the result to a native binary executable they can run faster than the same application on a regular JVM. Note that there is another sample in the Spring Graal Native Feature project that makes a function into a standalone web application (there is also a functional bean registration version of the same sample). You can run that on a lot of platforms that allow you to "bring your own container". (使用 Spring Cloud Function 是一種非常方便的方式來開發在 AWS 和其他平台上運行的函數。如果您還使用實驗性的 Spring Graal Native Feature 專案將結果編譯為原生二進位可執行檔,它們的運行速度會比在常規 JVM 上運行的相同應用程式更快。請注意,Spring Graal Native Feature 專案中有 另一個範例,將函數變成獨立的網路應用程式(還有相同範例的函數式 bean 註冊版本)。您可以在許多允許您「自帶容器」的平台上運行它。)

Get the Spring newsletter (取得 Spring 電子報)

Stay connected with the Spring newsletter (透過 Spring 電子報保持聯繫)

Subscribe (訂閱)

Get ahead (領先一步)

VMware offers training and certification to turbo-charge your progress. (VMware 提供培訓和認證,以加速您的進度。)

Learn more (了解更多)

Get support (取得支援)

Tanzu Spring offers support and binaries for OpenJDK™, Spring, and Apache Tomcat® in one simple subscription. (Tanzu Spring 在一個簡單的訂閱中提供對 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位檔案。)

Learn more (了解更多)

Upcoming events (即將舉行的活動)

Check out all the upcoming events in the Spring community. (查看 Spring 社群中所有即將舉行的活動。)

View all (查看所有)