在SAM中部署两个独立AWS Lambda及API Gateway集成问题排查
Let's break this down into two clear parts: first diagnosing why one of your Lambda functions is triggering an API Gateway timeout, then covering the best practices for deploying multiple Lambda functions from separate codebases using SAM.
Possible Causes for the API Gateway Timeout
Since one function works perfectly while the other doesn’t, the issue is likely specific to the misbehaving function or its integration. Here are the most common culprits to investigate:
- Lambda Execution Timeout or Unhandled Errors: Even though you set a 20-second timeout in your SAM template, if the problematic Lambda hits an unhandled exception or takes longer than 20 seconds to run, it will fail—and API Gateway will return a timeout as a result. Head to CloudWatch Logs for the failing function (likely
PetStoreClientFunction) and look for exceptions, stuck processes, or slow external API calls that might be dragging down execution. - Incorrect Handler Configuration: Double-check that
client.LambdaHandler::handleRequestexactly matches the actual class and method in yourpetstore-clientjar. A typo in the package name, class name, or method name will cause the Lambda to fail on invocation, which can manifest as a Gateway timeout. - Invalid CodeUri Path: Confirm the path
petstore-client/target/petstore-client-1.0-SNAPSHOT.jaris correct relative to your SAM template file. If the jar doesn’t exist at that location (maybe the build failed, or you ran the deploy from the wrong directory), Lambda will deploy an empty or invalid package, leading to invocation failures. - Insufficient IAM Permissions: While
AWSLambdaBasicExecutionRolelets the function write logs, if your client function needs to access other AWS services (like DynamoDB or S3), it will lack the necessary permissions. This can cause the function to hang or throw errors, resulting in a Gateway timeout. Check CloudWatch for "AccessDenied" errors to confirm this. - API Gateway Integration Glitch: Sometimes SAM’s automatic API Gateway integration can have hiccups. Verify in the API Gateway console that the
/client/{proxy+}endpoint is correctly linked toPetStoreClientFunction, and that the Lambda’s resource policy allows API Gateway to invoke it (SAM usually generates this automatically, but it’s worth checking if something went wrong during deployment).
Best Practices for Deploying Multiple Lambdas from Separate Codebases in SAM
Your current approach of using separate CodeUri paths is already valid, but here are ways to refine it and scale for future needs:
1. Stick to Separate Directories (Refine Your Current Setup)
Keeping each Lambda’s code in its own subdirectory (like petstore-server/ and petstore-client/) is a solid foundation. Just make sure:
- Each directory has its own build pipeline (e.g., Maven/Gradle for your Java projects) that generates a standalone jar in the
target/folder. - You run the build for both projects before executing
sam deploy --guided—this ensures the jar files exist at the paths specified inCodeUri.
2. Use SAM Build with Per-Function Build Commands
Instead of manually building each project first, let SAM handle the builds for you by adding Metadata to each function in your template. This is especially useful if your functions use different build tools or need custom build steps:
PetStoreServerFunction: Type: AWS::Serverless::Function Metadata: BuildMethod: maven BuildCommand: mvn clean package -DskipTests Properties: Handler: server.LambdaHandler::handleRequest Runtime: java8 CodeUri: petstore-server/ # ... rest of your properties PetStoreClientFunction: Type: AWS::Serverless::Function Metadata: BuildMethod: gradle BuildCommand: ./gradlew build shadowJar Properties: Handler: client.LambdaHandler::handleRequest Runtime: java8 CodeUri: petstore-client/ # ... rest of your properties
Now when you run sam build, SAM will execute the specified build command in each function’s directory, generate the correct jar, and package everything for deployment automatically.
3. Use Nested Applications for Larger Projects
If you anticipate growing this project with more functions or resources, split each Lambda into its own nested SAM application. This keeps each service’s code and configuration isolated:
- Create a separate SAM template for each function (e.g.,
petstore-server/server-template.yamlandpetstore-client/client-template.yaml). - Reference these nested apps in your main template:
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: "Client Service" Resources: PetStoreServerApp: Type: AWS::Serverless::Application Properties: Location: ./petstore-server/server-template.yaml # Add parameters if your nested app needs them PetStoreClientApp: Type: AWS::Serverless::Application Properties: Location: ./petstore-client/client-template.yaml # Add parameters if needed
This approach makes it easier to maintain, test, and deploy each function independently.
4. Validate Deployment Artifacts
After running sam build, check the .aws-sam/build/ directory to confirm each function’s build artifact (the jar file) exists and contains the correct code. This helps catch issues like failed builds or incorrect CodeUri paths before you deploy.
内容的提问来源于stack exchange,提问作者user152468

