我将 Spring boot jar 文件(它具有 lambda 请求流处理程序)作为 zip 文件上传到 AWS Lambda。由于 zip 很大,我在 S3 中上传并在 AWS 控制台中创建此 Lambda 函数时给出了该链接。正如我到处读到的那样,这就是使用简单方法在 lambda 中部署 Spring Boot 服务的全部内容。我的 Spring Boot 服务中有 2 个 GET 端点。请在下面找到完整的 Spring boot 服务代码和 Lambda 屏幕截图。
错误:(出现超时错误,因此在 Lambda 测试中增加到 15 分钟,结果如下,似乎仍然无法正常工作)
Executing function: succeeded (logs ) { "statusCode": 502, "multiValueHeaders": { "Content-Type": [ "application/json" ] }, "body": "{\"message\":\"Gateway timeout\"}", "isBase64Encoded": false }
Spring boot Lambda 请求流处理程序:(异步,因为我觉得 Lambda 最初需要很长时间才能启动)
public class StreamLambdaHandler implements RequestStreamHandler { private SpringBootLambdaContainerHandlerhandler; public StreamLambdaHandler() throws ContainerInitializationException { handler = new SpringBootProxyHandlerBuilder() .defaultProxy() .asyncInit() .springBootApplication(SlowApplication.class) .buildAndInitialize(); } @Override public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { handler.proxyStream(inputStream, outputStream, context); } }
build.gradle(我在此处添加了“task buildZip”以获取 zip 文件中的 build->“distributions”jar)
plugins { id 'java' id 'org.springframework.boot' version '3.1.0' id 'io.spring.dependency-management' version '1.1.0' } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '17' repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-test' implementation 'mysql:mysql-connector-java:8.0.32' implementation 'org.springframework.boot:spring-boot-starter-jdbc' implementation 'com.amazonaws:aws-lambda-java-core:1.2.2' implementation 'com.amazonaws:aws-lambda-java-events:3.11.1' implementation 'com.amazonaws.serverless:aws-serverless-java-container-spring:1.5.2' } task buildZip(type: Zip) { into('lib') { from(jar) from(configurations.runtimeClasspath) } } tasks.named('test') { useJUnitPlatform() } jar { duplicatesStrategy = DuplicatesStrategy.EXCLUDE manifest { attributes "Main-Class": "com.example.awstest" } from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } }
Spring Boot应用程序类:
package com.example.awstest.client; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @ComponentScan ("com.example.awstest") public class AWSTestApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(AWSTestApplication.class, args); } }
Spring 启动控制器:
package com.example.awstest.controller; @RestController public class AWSTestController { @Autowired private AWSTestServiceDAO awstestServiceDAO; @CrossOrigin(origins = "*") @GetMapping("/searchAllData") public ListsearchAllData() { List dataList = awstestServiceDAO.getAllData(); return dataList; } @CrossOrigin(origins = "*") @GetMapping("/searchDataByUser/{userno}") public List searchDataByUser(@PathVariable Integer userno) { List dataList = awstestServiceDAO.findDataByMemberNo(userno); return dataList; } }
Lambda 控制台:
添加处理程序为:com.example.awstest.handler.AWSLambdaHandler::handleRequest
测试功能:apigateway-awsproxy
{ "body": "eyJ0ZXN0IjoiYm9keSJ9", "resource": "/{proxy+}", "path": "/searchAllData", "httpMethod": "GET", "isBase64Encoded": true, "pathParameters": { "proxy": "/searchAllData" }, "stageVariables": { "baz": "qux" }, "headers": { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "en-US,en;q=0.8", "Cache-Control": "max-age=0", "CloudFront-Forwarded-Proto": "https", "CloudFront-Is-Desktop-Viewer": "true", "CloudFront-Is-Mobile-Viewer": "false", "CloudFront-Is-SmartTV-Viewer": "false", "CloudFront-Is-Tablet-Viewer": "false", "CloudFront-Viewer-Country": "US", "Host": "1234567890.execute-api.us-east-1.amazonaws.com", "Upgrade-Insecure-Requests": "1", "User-Agent": "Custom User Agent String", "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)", "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==", "X-Forwarded-For": "127.0.0.1, 127.0.0.2", "X-Forwarded-Port": "443", "X-Forwarded-Proto": "https" }, "multiValueHeaders": { "Accept": [ "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" ], "Accept-Encoding": [ "gzip, deflate, sdch" ], "Accept-Language": [ "en-US,en;q=0.8" ], "Cache-Control": [ "max-age=0" ], "CloudFront-Forwarded-Proto": [ "https" ], "CloudFront-Is-Desktop-Viewer": [ "true" ], "CloudFront-Is-Mobile-Viewer": [ "false" ], "CloudFront-Is-SmartTV-Viewer": [ "false" ], "CloudFront-Is-Tablet-Viewer": [ "false" ], "CloudFront-Viewer-Country": [ "US" ], "Host": [ "0123456789.execute-api.us-east-1.amazonaws.com" ], "Upgrade-Insecure-Requests": [ "1" ], "User-Agent": [ "Custom User Agent String" ], "Via": [ "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)" ], "X-Amz-Cf-Id": [ "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==" ], "X-Forwarded-For": [ "127.0.0.1, 127.0.0.2" ], "X-Forwarded-Port": [ "443" ], "X-Forwarded-Proto": [ "https" ] }, "requestContext": { "accountId": "123456789012", "resourceId": "123456", "stage": "prod", "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", "requestTime": "09/Apr/2015:12:34:56 +0000", "requestTimeEpoch": 1428582896000, "identity": { "cognitoIdentityPoolId": null, "accountId": null, "cognitoIdentityId": null, "caller": null, "accessKey": null, "sourceIp": "127.0.0.1", "cognitoAuthenticationType": null, "cognitoAuthenticationProvider": null, "userArn": null, "userAgent": "Custom User Agent String", "user": null }, "path": "/prod/searchAllData", "resourcePath": "/{proxy+}", "httpMethod": "GET", "apiId": "1234567890", "protocol": "HTTP/1.1" } }
错误:
s.exceptions.ContainerInitializationException: Could not initialize framework within the 20000ms timeout at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxy(LambdaContainerHandler.java:207) at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxyStream(LambdaContainerHandler.java:254) at com.example.awstest.handler.AWSLambdaHandler.handleRequest(AWSLambdaHandler.java:36) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) at com.amazonaws.services.lambda.runtime.api.client.EventHandlerLoader$StreamMethodRequestHandler.handleRequest(EventHandlerLoader.java:379) at com.amazonaws.services.lambda.runtime.api.client.EventHandlerLoader$2.call(EventHandlerLoader.java:903) at com.amazonaws.services.lambda.runtime.api.client.AWSLambda.startRuntime(AWSLambda.java:238) at com.amazonaws.services.lambda.runtime.api.client.AWSLambda.startRuntime(AWSLambda.java:190) at com.amazonaws.services.lambda.runtime.api.client.AWSLambda.main(AWSLambda.java:185) 04:36:48.470 [main] ERROR com.amazonaws.serverless.proxy.AwsProxyExceptionHandler -- Called exception handler for: com.amazonaws.serverless.exceptions.ContainerInitializationException: Could not initialize framework within the 20000ms timeout at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxy(LambdaContainerHandler.java:207) at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxyStream(LambdaContainerHandler.java:254) at com.example.awstest.handler.AWSLambdaHandler.handleRequest(AWSLambdaHandler.java:36) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) at com.amazonaws.services.lambda.runtime.api.client.EventHandlerLoader$StreamMethodRequestHandler.handleRequest(EventHandlerLoader.java:379) at com.amazonaws.services.lambda.runtime.api.client.EventHandlerLoader$2.call(EventHandlerLoader.java:903) at com.amazonaws.services.lambda.runtime.api.client.AWSLambda.startRuntime(AWSLambda.java:238) at com.amazonaws.services.lambda.runtime.api.client.AWSLambda.startRuntime(AWSLambda.java:190) at com.amazonaws.services.lambda.runtime.api.client.AWSLambda.main(AWSLambda.java:185) com.amazonaws.serverless.exceptions.ContainerInitializationException: Could not initialize framework within the 20000ms timeout at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxy(LambdaContainerHandler.java:207) at com.amazonaws.serverless.proxy.internal.LambdaContainerHandler.proxyStream(LambdaContainerHandler.java:254) at com.example.awstest.handler.AWSLambdaHandler.handleRequest(AWSLambdaHandler.java:36) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) at com.amazonaws.services.lambda.runtime.api.client.EventHandlerLoader$StreamMethodRequestHandler.handleRequest(EventHandlerLoader.java:379) at com.amazonaws.services.lambda.runtime.api.client.EventHandlerLoader$2.call(EventHandlerLoader.java:903) at com.amazonaws.services.lambda.runtime.api.client.AWSLambda.startRuntime(AWSLambda.java:238) at com.amazonaws.services.lambda.runtime.api.client.AWSLambda.startRuntime(AWSLambda.java:190) at com.amazonaws.services.lambda.runtime.api.client.AWSLambda.main(AWSLambda.java:185) END RequestId: 21464e19-8dee-47e0-9acd-5ae04d24431a REPORT RequestId: 21464e19-8dee-47e0-9acd-5ae04d24431a Duration: 20003.03 ms Billed Duration: 20004 ms Memory Size: 512 MB Max Memory Used: 137 MB
En regardant vos fichiers Gradle, vous utilisez une version de conteneur Java sans serveur AWS très ancienne et obsolète qui n'est pas compatible avec Spring Boot 3.x.
Supprimer
com.amazonaws.serverless:aws-serverless-java-container-spring:1.5.2
并将其替换为com.amazonaws.serverless:aws-serverless-java-container -springboot3:2.0.0-M1
. Vous pouvez également comparer surhttps://github.com/awslabs/aws-serverless-java-container/tree/main/samples/springboot3/pet-store.Si vous rencontrez des problèmes de délai d'attente similaires à l'avenir, vous pouvez également activerAWS X-RayouOpenTelemetrypour collecter des données de suivi et voir où le temps est perdu.