Java 重返 Lambda:使用 Spring Boot 3、SnapStart 和 Bedrock 构建亚秒级 GenAI API

发布: (2025年12月16日 GMT+8 21:10)
4 min read
原文: Dev.to

Source: Dev.to

Cover image for Java is Back on Lambda: Building a Sub-Second GenAI API with Spring Boot 3, SnapStart, and Bedrock

Java 对 AWS Lambda 来说太慢吗?多年来,答案是“是的,主要是因为可怕的冷启动”。如今,借助 Java 21SnapStart,答案是“绝对不是”。

在本文中,我展示了如何使用 Spring Boot 3Java 21 和 AWS Bedrock(Claude 3.5)构建一个生产级的无服务器 API,其启动时间不足 500 ms

The Problem: The “Cold Start” Tax

If you’ve run Java on Lambda before, you know the pain. The JVM is heavy; loading classes, initializing the Spring context, and setting up AWS SDKs can take 5 to 15 seconds.

  • Asynchronous background jobs can tolerate this.
  • Synchronous APIs (e.g., chatbots or REST endpoints) cannot.

解决方案:AWS Lambda SnapStart

SnapStart 通过使用 CRaC(Coordinated Restore at Checkpoint)改变了游戏规则。

  1. AWS 在 部署阶段 启动你的函数。
  2. 它执行完整的初始化(JVM 预热、Spring 上下文、依赖注入)。
  3. 它对已初始化的 Firecracker 微型 VM 进行内存快照。
  4. 它将此快照进行缓存。

当用户调用 API 时,Lambda 只需 恢复内存状态——就像从休眠中唤醒笔记本电脑,而不是进行冷启动。

架构概述

该项目通过 Spring Cloud Function 集成生成式 AI(AWS Bedrock)。

关键组件

组件详情
RuntimeJava 21 (AWS Corretto)
FrameworkSpring Boot 3.2 + Spring Cloud Function
InfrastructureTerraform
AI ModelAnthropic Claude 3.5 Sonnet(通过 AWS Bedrock)

代码:优化技术

1. 智能初始化(构造函数注入)

繁重的工作(创建 Bedrock 客户端)被移到构造函数中,这样 SnapStart 在部署期间捕获它,而不是在调用期间。

@Service
public class BedrockService {
    private final BedrockRuntimeClient bedrockClient;

    public BedrockService() {
        // CRITICAL: runs during the "Deployment" phase, not the "Invocation" phase!
        this.bedrockClient = BedrockRuntimeClient.builder()
            .region(Region.US_EAST_1)
            // Use the lightweight HTTP client instead of Netty
            .httpClient(UrlConnectionHttpClient.builder().build())
            .build();
    }

    // ... business logic ...
}

专业提示: 将默认的 Netty HTTP 客户端替换为 UrlConnectionHttpClient 可以减小构件体积并缩短启动时间,这对 Lambda 性能至关重要。

2. Terraform 配置

启用 SnapStart 只需一行代码,但还必须启用版本发布。

resource "aws_lambda_function" "java_snapstart_function" {
  function_name = "java-bedrock-poc"
  runtime       = "java21"
  handler       = "org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest"

  # ... other config ...

  publish = true  # REQUIRED for SnapStart

  snap_start {
    apply_on = "PublishedVersions"
  }

  environment {
    variables = {
      # Tune JVM for fast tier‑1 compilation
      JAVA_TOOL_OPTIONS = "-XX:+TieredCompilation -XX:TieredStopAtLevel=1"
    }
  }
}

基准测试:它有效吗?

我部署了函数并使用 AWS CLI 进行测试。差别天壤之别。

指标未使用 SnapStart使用 SnapStart 🚀
初始化时长~8,000 毫秒0 毫秒(已缓存)
恢复时长不适用~350 毫秒
执行时长~1,500 毫秒~1,500 毫秒
总用户等待时间~9.5 秒 🐢~1.8 秒 🚀

*注:*执行时间包括对 Claude 3.5(GenAI)的调用。Java Lambda 的开销降至亚秒级。

结论

Java 在无服务器世界中不再是二等公民。通过结合 Spring Boot 3、SnapStart 和轻量级客户端,我们可以构建企业级、强类型且可测试的应用程序,其性能可与 Node.js 或 Python 相媲美。

对于处理遗留迁移的高级架构师而言,这提供了一条可行的路径,将复杂的单体应用迁移到 AWS,而无需用新语言重写所有代码。

源代码

完整的工作示例(包括 Terraform 代码和专用的 shell 脚本)可在 GitHub 上获取:

github.com/jmontagne/poc_java_lambda_snapstart_bedrock

Back to Blog

相关文章

阅读更多 »