Go函数必须调用lambda.Start作为入口,否则Lambda无法识别;需严格匹配handler签名与事件结构体,编译须用GOOS=linux且strip符号表,context要透传至阻塞操作,敏感配置应通过SSM按需加载并缓存,/tmp目录需手动清理。

Go函数必须实现 lambda.Start 入口才能被Lambda识别
Go编译成二进制后,Lambda运行时无法自动发现主函数,必须显式调用 lambda.Start 启动事件循环。不这么做会直接报错:fork/exec /var/task/bootstrap: no such file or directory(其实是找不到有效入口,不是文件缺失)。
常见错误是写了个普通 main() 函数但没调用 lambda.Start,或者把 handler 传错类型——它只接受 func(context.Context, T) (U, error) 或 func(context.Context, []byte) ([]byte, error) 这两类签名。
- handler 参数类型必须和触发事件结构体严格匹配(比如 API Gateway v2 用
events.APIGatewayV2HTTPRequest,S3 事件用events.S3Event) - 别在 handler 外部做耗时初始化(如数据库连接),Lambda 可能复用实例,但冷启动时仍需保证 handler 内部轻量
- 本地测试时用
lambda.StartHandler+events包构造模拟输入,别依赖os.Args
构建二进制必须用 GOOS=linux GOARCH=amd64(或 arm64)
Lambda 宿主机是 Linux,且不支持 macOS/Windows 编译产物。直接在本机 go build 默认生成的是当前系统架构,上传后运行会报 exec format error。
ARM64 架构(Graviton2)虽省成本,但要注意:某些 Cgo 依赖(如 net 库的 DNS 解析)在 ARM 上行为略有差异;若用到 cgo,还需同步设置 CGO_ENABLED=1 并指定对应平台的交叉编译工具链。
立即学习“go语言免费学习笔记(深入)”;
- 推荐命令:
GOOS=linux GOARCH=arm64 go build -o main main.go - 务必 strip 符号表:
go build -ldflags="-s -w" -o main main.go,否则二进制可能超 50MB 限制 - 如果项目含 cgo,确认
CC_FOR_TARGET指向正确的交叉编译器(如aarch64-linux-gnu-gcc)
context.Context 要传给所有可能阻塞的操作
Lambda 的超时由 context.Context 控制,但 Go 的 http.Client、database/sql、甚至 time.Sleep 都不会自动感知它。不传递会导致函数看似“卡住”,实则已超时被强制终止,日志里只看到 Task timed out,无其他线索。
典型场景是调用下游 HTTP 接口或查询 DynamoDB:默认 http.DefaultClient 没设 timeout,一旦网络抖动就拖垮整个函数。
- HTTP 请求必须用带 context 的方法:
client.Do(req.WithContext(ctx)),而非client.Get(...) - DynamoDB 客户端建议用
dynamodbattribute.UnmarshalWithContext替代无 context 版本 - 避免在 handler 中起 goroutine 后丢弃(如
go sendToKinesis(...)),未完成的任务会被静默截断
环境变量和 Secrets 最好通过 os.Getenv + ssm.GetParameter 分层管理
硬编码密钥或把敏感配置全塞进 Lambda 环境变量,既违反最小权限原则,又让部署包难以复用。AWS 推荐用 SSM Parameter Store(或 Secrets Manager)存敏感值,运行时按需拉取。
但注意:SSM 调用本身也耗时,且受 Lambda 并发限制影响。高频调用(如每请求都查一次)会拖慢响应;一次性加载又可能因缓存失效导致后续请求拿不到新值。
- 非敏感配置(如
STAGE=prod)走环境变量,用os.Getenv直接读 - 敏感值首次访问时用
ssm.GetParameter加载,并缓存在包级变量(加sync.Once防竞态) - 别在 init() 里预加载 SSM 参数——冷启动时上下文未就绪,
context.Background()可能导致超时失败
最易被忽略的一点:Lambda 的 /tmp 是实例级共享的,且大小上限 512MB。如果函数里生成临时文件却没清理,复用容器时可能因磁盘满而崩溃——错误日志里往往只显示 exit status 1,得手动加 df -h 日志才能定位。










