AWS Lambda连接MongoDB Atlas基础示例超时问题求助
我按照MongoDB官方教程尝试通过AWS Lambda连接MongoDB Atlas,但测试Lambda函数时出现超时错误。多次测试后怀疑问题出在collection.Find(...)请求环节。相关代码及日志如下:
main.go
package main import ( "context" "log" "os" "github.com/aws/aws-lambda-go/lambda" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) type EventInput struct { Limit int64 `json:"limit"` } type Movie struct { ID primitive.ObjectID `bson:"_id" json:"_id"` Title string `bson:"title" json:"title"` Year int32 `bson:"year" json:"year"` } var client, err = mongo.Connect(context.Background(), options.Client().ApplyURI(os.Getenv("ATLAS_URI"))) func HandleRequest(ctx context.Context, input EventInput) ([]Movie, error) { if err != nil { return nil, err } collection := client.Database("sample_mflix").Collection("movies") opts := options.Find() if input.Limit != 0 { opts = opts.SetLimit(input.Limit) } cursor, err := collection.Find(context.Background(), bson.M{}, opts) if err != nil { return nil, err } var movies []Movie if err = cursor.All(context.Background(), &movies); err != nil { return nil, err } return movies, nil } func main() { lambda.Start(HandleRequest) }
go.mod
module aws-lambdaexample go 1.20 require ( github.com/aws/aws-lambda-go v1.41.0 // indirect github.com/golang/snappy v0.0.1 // indirect github.com/joho/godotenv v1.5.1 // indirect github.com/klauspost/compress v1.13.6 // indirect github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect github.com/pkg/errors v0.9.1 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.1 // indirect github.com/xdg-go/stringprep v1.0.3 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect go.mongodb.org/mongo-driver v1.11.6 // indirect golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/text v0.3.7 // indirect )
Lambda函数日志
START RequestId: 9b96311b-2211-4d94-82c6-3bc0f2fd00a2 Version: $LATEST 2023-05-10T08:32:29.025Z 9b96311b-2211-4d94-82c6-3bc0f2fd00a2 Task timed out after 2.00 seconds
网络权限配置错误
如果Lambda部署在VPC内,需确保安全组允许出站访问MongoDB Atlas的默认端口27017,同时MongoDB Atlas的IP白名单要包含Lambda所在VPC的NAT网关IP(公网访问场景)或VPC的CIDR段(VPC peering场景)。若Lambda未部署在VPC,可临时将Atlas白名单设置为0.0.0.0/0(仅测试用,生产环境需严格限制IP)。上下文使用不当
代码中collection.Find和cursor.All都使用了context.Background(),但Lambda处理函数已传入包含超时取消信号的ctx。使用Background会导致请求无视Lambda的超时设置,一直等待直到被强制终止。修改为使用传入的上下文:cursor, err := collection.Find(ctx, bson.M{}, opts) // ... if err = cursor.All(ctx, &movies); err != nil {MongoDB客户端初始化问题
全局变量初始化mongo.Connect使用context.Background(),冷启动时可能连接未建立就进入处理逻辑,且初始化失败后err会持续影响后续请求。建议在处理函数内用sync.Once确保客户端仅初始化一次,同时使用带超时的上下文:import "sync" import "time" var ( client *mongo.Client initOnce sync.Once initErr error ) func HandleRequest(ctx context.Context, input EventInput) ([]Movie, error) { initOnce.Do(func() { connectCtx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() client, initErr = mongo.Connect(connectCtx, options.Client().ApplyURI(os.Getenv("ATLAS_URI"))) }) if initErr != nil { return nil, initErr } // ... 后续业务逻辑 }Lambda超时时间过短
当前Lambda超时设置为2秒,对于数据库连接和查询来说太短,尤其是冷启动场景。临时将超时时间调整至10秒左右测试,后续再根据实际执行时长优化。
内容的提问来源于stack exchange,提问作者Sinfo

