如何用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(); } } }
关键细节解释
- 超时配置:
readTimeout设置为4分钟,确保HTTP客户端不会在Lambda执行完成前触发超时。 - 资源管理:
try-with-resources模式自动关闭LambdaAsyncClient,避免资源泄漏。 - 回调逻辑:
whenComplete方法实现非阻塞处理,适合不需要立即等待结果的异步业务场景;若需同步等待,使用futureResponse.get()并处理中断、执行异常。 - 状态判断:除捕获异常外,通过
InvokeResponse.statusCode()可进一步确认Lambda执行状态,200表示执行成功,其他状态码需根据业务场景处理。
内容的提问来源于stack exchange,提问作者Nid
相关产品推荐
相关产品推荐

