我使用spring boot创建了一个rest api lambda。当我从中创建一个jar文件并使用terraform将其部署到localstack时,我可以调用api,它按预期工作。
但是,当我从代码中创建docker映像并采用terraform来使用该image_uri时,当我调用api时,我得到以下错误:
Lambda runtime initialization error for function arn:aws:lambda:eu-west-2:000000000000:function:restapi: b'{"errorMessage":"Error loading class com.example.lambda.StreamLambdaHandler: Metaspace","errorType":"java.lang.OutOfMemoryError"}'
这是地形:
variable "STAGE" {
type = string
default = "local"
}
variable "AWS_REGION" {
type = string
default = "eu-west-2"
}
variable "IMG_URI" {
type = string
default = "localhost:4510/com.example-restapi-lambda:1.0.0"
}
variable "FUNCTION_NAME" {
type = string
default = "restapi"
}
variable "FUNCTION_HANDLER" {
type = string
default = "com.example.lambda.StreamLambdaHandler"
}
provider "aws" {
access_key = "test_access_key"
secret_key = "test_secret_key"
region = var.AWS_REGION
s3_force_path_style = true
skip_credentials_validation = true
skip_metadata_api_check = true
skip_requesting_account_id = true
endpoints {
apigateway = var.STAGE == "local" ? "http://localhost:4566" : null
cloudformation = var.STAGE == "local" ? "http://localhost:4566" : null
cloudwatch = var.STAGE == "local" ? "http://localhost:4566" : null
cloudwatchevents = var.STAGE == "local" ? "http://localhost:4566" : null
iam = var.STAGE == "local" ? "http://localhost:4566" : null
lambda = var.STAGE == "local" ? "http://localhost:4566" : null
s3 = var.STAGE == "local" ? "http://localhost:4566" : null
}
}
resource "aws_iam_role" "lambda-execution-role" {
name = "lambda-execution-role-${var.FUNCTION_NAME}"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_lambda_function" "restApiLambdaFunction" {
image_uri = var.IMG_URI
function_name = var.FUNCTION_NAME
role = aws_iam_role.lambda-execution-role.arn
handler = var.FUNCTION_HANDLER
# handler = "org.springframework.cloud.function.adapter.aws.FunctionInvoker"
runtime = "java11"
timeout = 60
environment {
variables = {
MAIN_CLASS = "com.example.lambda.AWSLambdaApp"
# JAVA_OPTS = "-Xmx5g"
}
}
}
resource "aws_api_gateway_rest_api" "rest-api" {
name = "RestApi-${var.FUNCTION_NAME}"
}
resource "aws_api_gateway_resource" "proxy" {
rest_api_id = aws_api_gateway_rest_api.rest-api.id
parent_id = aws_api_gateway_rest_api.rest-api.root_resource_id
path_part = "{proxy+}"
}
resource "aws_api_gateway_method" "proxy" {
rest_api_id = aws_api_gateway_rest_api.rest-api.id
resource_id = aws_api_gateway_resource.proxy.id
http_method = "ANY"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "proxy" {
rest_api_id = aws_api_gateway_rest_api.rest-api.id
resource_id = aws_api_gateway_method.proxy.resource_id
http_method = aws_api_gateway_method.proxy.http_method
integration_http_method = "POST"
type = "AWS_PROXY"
uri = aws_lambda_function.restApiLambdaFunction.invoke_arn
}
resource "aws_api_gateway_deployment" "rest-api-deployment" {
depends_on = [aws_api_gateway_integration.proxy]
rest_api_id = aws_api_gateway_rest_api.rest-api.id
stage_name = var.STAGE
}
resource "aws_cloudwatch_event_rule" "warmup" {
name = "warmup-event-rule-${var.FUNCTION_NAME}"
schedule_expression = "rate(10 minutes)"
}
resource "aws_cloudwatch_event_target" "warmup" {
target_id = "warmup"
rule = aws_cloudwatch_event_rule.warmup.name
arn = aws_lambda_function.restApiLambdaFunction.arn
input = "{"httpMethod": "SCHEDULE", "path": "warmup"}"
}
resource "aws_lambda_permission" "warmup-permission" {
statement_id = "AllowExecutionFromCloudWatch"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.restApiLambdaFunction.function_name
principal = "events.amazonaws.com"
source_arn = aws_cloudwatch_event_rule.warmup.arn
}
我所看到的最接近的解决方案是将JAVA_OPTS传递给docker映像,增加可用内存,但不确定如何通过terraform做到这一点。虽然我不确定这是否能解决问题。如有任何指导,将不胜感激。
根据我的评论,在aws_lambda_function
资源中有一个memory_size
选项[1]。如果没有定义,它将默认为128MB。它可能需要增加,以避免OOM错误。
[1] https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function memory_size