在 GCP 上运行基于 Java 的 API 后端(Spring Boot、Micronaut、Quarkus)最经济有效的方法是啥?

Posted

技术标签:

【中文标题】在 GCP 上运行基于 Java 的 API 后端(Spring Boot、Micronaut、Quarkus)最经济有效的方法是啥?【英文标题】:What is the most cost-effective way to run a Java based API back-end (Spring Boot, Micronaut, Quarkus) on GCP?在 GCP 上运行基于 Java 的 API 后端(Spring Boot、Micronaut、Quarkus)最经济有效的方法是什么? 【发布时间】:2020-11-29 13:33:32 【问题描述】:

我有一个移动应用程序,其后端当前作为 NodeJS 云函数运行,但我对 NodeJS 的使用远不如对 Java 的使用舒适。所以,我用 Java 重写了 API——但是,当它部署为 Cloud Function 或 Cloud Run 时,冷启动性能显然不是很好。当我添加我需要的依赖项时,我看到了 15 秒的冷启动时间,这是行不通的。我确实有一个“预热”端点,当用户登录移动应用程序以启动 API 后端的初始化时,我会立即调用它,这确实有点帮助。

我一直在玩 GraalVM 并生成本机映像有一段时间了,虽然我可以让您的基本 hello-world 应用程序和一些更复杂的示例正常工作,但我的应用程序有一些依赖项,例如 gRPC 和 Cloud Firestore 等,而我还没有成功地使用 Micronaut、Quarkus 或 Spring Boot 为其生成本机映像。

我考虑在一个至少有 1 个的托管实例组上运行,因此始终至少有一个实例启动并运行,准备好为请求提供服务,但我需要一个云负载均衡器,而且我已经阅读了一些恐怖故事云负载均衡器最终使人们付出的代价比他们预期的要多得多。

有没有办法使用 Cloud Endpoints 管理托管实例组?我知道你可以在哪里使用单个 VM 实例,但不能跨组,这让我相信在这种情况下我需要一个 Cloud Loadbalancer 来做我需要的事情?

成本效益很重要,因为我的应用是超级新的,还没有产生任何收入,而且由于我只是用个人资金资助它,所以我的基础设施预算不是特别高:)

TL;DR/ 寻找有关在 GCP 上的 Micronaut、Quarkus 或 Spring Boot 等框架上托管基于 Java 的 API 应用程序的最便宜方法的提示,同时保持良好的性能和弹性。

任何见解将不胜感激。

【问题讨论】:

【参考方案1】:

我写了an article on Java framework cold start on Cloud Run(结果已经过时了,因为在这篇文章发布并与谷歌人讨论之后,团队已经更新了 Cloud Run 平台和管理 Java 容器的方式。现在他们现在开始快了!)

无论如何,您的问题一开始似乎很相关,但最终并非如此。我会解释原因。

首先,冷启动是一个暂时的问题。你的第一个请求很慢,后面几十个,几百个很快。真的有问题吗?

如果是这样,最小实例功能(目前仅在 CLoud Run for Anthos 上可用)将出现在托管版本中。像这样你永远不会真正扩展到 0,实例保持温暖并立即启动(但是,作为对应方,它不会是免费的)。

其次,如果您寻求可维护性,我向您推荐您知道的框架。您将更有效率地改进您的代码、解决您的问题并节省您的时间(时间就是金钱),而不仅仅是考虑基础设施!

所有 Java 框架在优化时都比较接近(Naive Spring Boot on Cloud Run 20s 开始,打包优化后 2s!)。当然,原生编译(使用 GraalVM)是最快的,但它目前还不是很稳定,有一些副作用(我不推荐它用于生产)。

个人意见:我是 Spring Boot 及其生态系统的忠实粉丝。但是 Micronaut 和它的 AOT 编译,除了符合 Spring Boot 习惯用法的注释之外,绝对很棒。 Quarkus 是较新的,我对此没有真正的看法(从未在生产/实际项目中使用过)

【讨论】:

我实际上已经为您的文章添加了书签,并且大量引用了它——它非常有帮助!理想情况下,我很想使用本机映像,但就像您提到的那样,我发现本机映像编译目前还不是超级稳定。我试过没有原生镜像编译的 Spring Boot、Micronaut 和 Quarkus,冷启动时间约为 15s非常新,它有一段时间不活动,我担心冷启动延迟会阻止新用户。【参考方案2】:

如果您以性能为目标,我会说您需要更多的 Micronaut 或 Quarkus 与 GraalVM 结合使用。定义要运行的服务

我的经验主要是使用 Micornaut 无服务器应用程序,并且可以管理以函数/lambda 形式运行的 api 服务,启动时间为 100-500 毫秒。如果您启用配置(AWS 中自 12.2019 起提供该功能),冷启动不再是一个大问题,您可以跳过所谓的warming

如何让你的 lambda 更快?

    尽量减小包大小(删除所有使用了一小部分的大型库)- 将包大小保持在最大 20 MB。每次冷启动时都会提取并解压缩此包。 如果您的服务使用 JVM 技术,请尝试将它们迁移到 Graalvm,从而将启动开销降至最低。 micronaut + graalvm quarkus + graalvm helidon + graalvm 使用云基础架构配置来减少冷启动。 这是 AWS 提供的,不确定 GPC

https://aws.amazon.com/about-aws/whats-new/2019/12/aws-lambda-announces-provisioned-concurrency/

注意:在启动和冷启动方面,到目前为止,与 GCP 相比,恕我直言,AWS 为无服务器应用程序设置了更好的设置。

【讨论】:

以上是关于在 GCP 上运行基于 Java 的 API 后端(Spring Boot、Micronaut、Quarkus)最经济有效的方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

无法在 GCP 上打开 vm 实例的 ssh:无法连接到后端(代码:4003)

从 Google GCP 项目凭据 API 密钥中检索信息

在 GCP App Engine 上部署 Django、Django REST Framework 后端和 VueJS + webpack 前端(标准)

GCP API Gateway:路径参数作为查询参数传递

如何在 GCP 上运行的 Kafka 服务器中处理 GCP 外部的消息

GoogleIdTokenVerifier 不返回名称、图片等