Get ahead (领先一步)
VMware offers training and certification to turbo-charge your progress. (VMware 提供培训和认证,以加速您的进步。)
Learn more (了解更多)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 (这是 AWS Lambda 上 Spring Cloud Function 的最新内存与计费图。它显示了计费指标 GBsec 作为 Lambda 中内存分配的函数,用于两个自定义运行时,一个使用纯 Java,一个使用 GraalVM 原生镜像,正如 Andy Clement 最近在这篇博客中描述的那样)
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 版本的显着改进,并且还具有我在此再次使用的自定义运行时(因此橙色条与上图中的红色条等效))
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 优化,您可以在较低的内存设置下使用它。)
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
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 项目中还有另一个示例,它将函数转换为独立的 Web 应用程序(还有相同示例的函数式 bean 注册版本)。您可以在许多允许您“自带容器”的平台上运行它。)