You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Java调用software.amazon.awssdk异步Lambda函数并获取结果

解决Spring Boot调用Lambda 504超时问题:异步调用实现

我在Spring Boot应用中使用software.amazon.awssdk 2.18.21版本调用Lambda函数,该函数执行耗时约2-3分钟,调用时抛出Http 504网关超时异常。需要改用异步调用Lambda函数并读取响应,判断执行成功或失败。

原同步调用代码

// imports
import software.amazon.awssdk.http.ApacheHttpClient;
import software.amazon.awssdk.services.lambda.LambdaClient;
import software.amazon.awssdk.services.lambda.model.InvokeRequest;
import software.amazon.awssdk.services.lambda.model.InvokeResponse;
import java.time.Duration;

// 调用Lambda函数
try{
  LambdaClient client = LambdaClient.builder().httpClientBuilder(ApacheHttpClient.builder()
                      .maxConnections(100)
                      .socketTimeout(Duration.ofSeconds(60))
                      .connectionTimeout(Duration.ofSeconds(60))
                    ).build();
  InvokeRequest req = InvokeRequest.builder().functionName("abc").build();
  InvokeResponse res = client.invoke(req);
  String response = res.payload().asUtf8String();
  System.out.println(response);
}catch(Exception e){
  e.printStackTrace();
}

我尝试的异步代码(未完成)

import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient;
import software.amazon.awssdk.http.SdkAsyncHttpClient;
import software.amazon.awssdk.services.lambda.LambdaAsyncClient;
import software.amazon.awssdk.services.lambda.model.InvokeRequest;
import software.amazon.awssdk.services.lambda.model.InvokeResponse;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;

try{
SdkAsyncHttpClient client = NettyNioAsyncHttpClient.builder().readTimeout(Duration.ofSeconds(60)).connectionTimeout(Duration.ofSeconds(60)).build();

  LambdaAsyncClient lambdaClient = LambdaAsyncClient.builder().httpClient(client).build();
  InvokeRequest req = InvokeRequest.builder().functionName("abc").invocationType("EVENT").build();
CompletableFuture<InvokeResponse> request = lambdaClient.invoke(req);
  // InvokeResponse res = client.invoke(req);
  // String response = res.payload().asUtf8String();
  // System.out.println(response);
}catch(Exception e){
  e.printStackTrace();
}

正确的异步调用实现方案

核心注意事项

  • 若要获取Lambda执行的完整响应结果,不能使用EVENT调用类型——该模式是"触发即返回",仅确认请求已提交,不会返回函数执行的payload。需使用默认的REQUEST_RESPONSE类型,配合异步客户端的CompletableFuture实现非阻塞调用,同时调整HTTP客户端超时时间以覆盖Lambda的2-3分钟执行时长。
  • 必须正确处理CompletableFuture的回调逻辑,包括成功响应解析、异常捕获,以及客户端资源的自动释放。

完整代码示例

import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient;
import software.amazon.awssdk.services.lambda.LambdaAsyncClient;
import software.amazon.awssdk.services.lambda.model.InvokeRequest;
import software.amazon.awssdk.services.lambda.model.InvokeResponse;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;

public class LambdaAsyncInvoker {

    public void invokeLambdaAsync() {
        // 构建异步HTTP客户端,设置足够长的读取超时(覆盖Lambda执行时长)
        NettyNioAsyncHttpClient asyncHttpClient = NettyNioAsyncHttpClient.builder()
                .readTimeout(Duration.ofMinutes(4)) // 设为比Lambda执行时间更长的值
                .connectionTimeout(Duration.ofSeconds(60))
                .build();

        // 使用try-with-resources自动管理Lambda客户端资源
        try (LambdaAsyncClient lambdaClient = LambdaAsyncClient.builder()
                .httpClient(asyncHttpClient)
                .build()) {

            // 构建调用请求,默认使用REQUEST_RESPONSE类型(可省略显式声明)
            InvokeRequest invokeRequest = InvokeRequest.builder()
                    .functionName("abc")
                    // .invocationType(InvocationType.REQUEST_RESPONSE) // 默认值,无需显式设置
                    .build();

            // 发起异步调用,获取CompletableFuture
            CompletableFuture<InvokeResponse> futureResponse = lambdaClient.invoke(invokeRequest);

            // 非阻塞式处理异步结果
            futureResponse.whenComplete((response, exception) -> {
                if (exception != null) {
                    // 处理调用异常(如超时、权限错误、Lambda执行报错等)
                    System.err.println("Lambda调用失败: " + exception.getMessage());
                    exception.printStackTrace();
                } else {
                    // 解析并处理Lambda执行结果
                    String payload = response.payload().asUtf8String();
                    System.out.println("Lambda执行输出: " + payload);

                    // 通过状态码判断执行状态
                    if (response.statusCode() == 200) {
                        System.out.println("Lambda执行成功");
                    } else {
                        System.err.println("Lambda执行返回异常状态码: " + response.statusCode());
                    }
                }
            });

            // 若业务需要同步等待结果,可取消注释以下代码
            // try {
            //     InvokeResponse response = futureResponse.get();
            //     // 同步处理响应逻辑
            // } catch (Exception e) {
            //     e.printStackTrace();
            // }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

关键细节解释

  1. 超时配置:readTimeout设置为4分钟,确保HTTP客户端不会在Lambda执行完成前触发超时。
  2. 资源管理:try-with-resources模式自动关闭LambdaAsyncClient,避免资源泄漏。
  3. 回调逻辑:whenComplete方法实现非阻塞处理,适合不需要立即等待结果的异步业务场景;若需同步等待,使用futureResponse.get()并处理中断、执行异常。
  4. 状态判断:除捕获异常外,通过InvokeResponse.statusCode()可进一步确认Lambda执行状态,200表示执行成功,其他状态码需根据业务场景处理。

内容的提问来源于stack exchange,提问作者Nid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 14:40:15