You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 12:50:38