本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
Go 中的 Amazon Lambda 函数处理程序
Lambda 函数处理程序是函数代码中处理事件的方法。当调用函数时,Lambda 运行处理程序方法。您的函数会一直运行,直到处理程序返回响应、退出或超时。
在 Gomain()
函数。
例 Go Lambda 函数
package main import ( "context" "fmt" "github.com/aws/aws-lambda-go/lambda" ) type MyEvent struct { Name string `json:"name"` } func HandleRequest(ctx context.Context, event *MyEvent) (*string, error) { if event == nil { return nil, fmt.Errorf("received nil event") } message := fmt.Sprintf("Hello %s!", event.Name) return &message, nil } func main() { lambda.Start(HandleRequest) }
下面是此函数的输入示例:
{ "name": "Jane" }
请注意以下几点:
-
package main:在 Go 中,包含
func main()
的程序包必须始终名为main
。 -
import:您可以使用它来包含 Lambda 函数所需的库。在此实例中,它包括:
-
fmt:用于格式化您的函数返回的值的 Go 格式化
对象。 -
github.com/aws/ aws-lambda-go /lambda:如前所述,实现了 Go 的 Lambda 编程模型。
-
func HandleRequest (ctx context.Context,event *MyEvent)(*字符串,错误):这是你的 Lambda 处理程序的签名。它是 Lambda 函数的入口点,包含调用函数时执行的逻辑。此外,包含的参数表示以下含义:
-
ctx context.Context:为您的 Lambda 函数调用提供运行时信息。
ctx
是您声明的变量,用于利用通过 Go 中的 Amazon Lambda上下文对象 提供的信息。 -
e@@ vent * MyEvent:这是一个指向
event
的名为的参数MyEvent
。它表示 Lambda 函数的输入。 -
*string, error:处理程序返回两个值。第一个是指向包含 Lambda 函数结果的字符串的指针。第二个是错误类型,如果没有错误,则为
nil
;如果出错,则包含标准错误信息。有关自定义错误处理的更多信息,请参阅Go 中的 Amazon Lambda 函数错误。 -
return &message, nil:返回两个值。第一个是指向字符串消息的指针,它是使用输入事件中的
Name
字段构造的问候语。第二个值nil
表示该函数没有遇到任何错误。
-
-
func main():这是运行您的 Lambda 函数代码的入口点。该项为必填项。
通过在
func main(){}
代码括号之间添加lambda.Start(HandleRequest)
,可以执行您的 Lambda 函数。按照 Go 语言标准,开括号即{
必须直接置于main
函数签名末尾。
命名
- provided.al2 与 provided.al2023 运行时系统
-
对于使用 .zip 部署包中的
provided.al2
或provided.al2023
运行时系统的 Go 函数,包含函数代码的可执行文件必须命名为bootstrap
。如果使用 .zip 文件部署函数,bootstrap
文件必须位于 .zip 文件的根目录中。对于使用容器映像中的provided.al2
或provided.al2023
运行时系统的 Go 函数,可执行文件可以使用任何名称。处理程序可以使用任何名称。要在代码中引用处理程序值,可以使用
_HANDLER
环境变量。 - go1.x 运行时系统
-
对于使用
go1.x
运行时系统的 Go 函数,可执行文件和处理程序可以共享任何名称。例如,如果您将处理程序的值设置为Handler
,Lambda 将在Handler
可执行文件中调用该main()
函数。
要在 Lambda 控制台中更改函数处理程序名称,请在 Runtime settings(运行时设置)窗格中,选择 Edit(编辑)。
使用结构化类型的 Lambda 函数处理程序
在上述示例中,输入类型是简单的字符串。但是,您也可以将结构化事件传递到您的函数处理程序:
package main import ( "fmt" "github.com/aws/aws-lambda-go/lambda" ) type MyEvent struct { Name string `json:"What is your name?"` Age int `json:"How old are you?"` } type MyResponse struct { Message string `json:"Answer"` } func HandleLambdaEvent(event *MyEvent) (*MyResponse, error) { if event == nil { return nil, fmt.Errorf("received nil event") } return &MyResponse{Message: fmt.Sprintf("%s is %d years old!", event.Name, event.Age)}, nil } func main() { lambda.Start(HandleLambdaEvent) }
下面是此函数的输入示例:
{ "What is your name?": "Jim", "How old are you?": 33 }
响应类似于以下示例:
{ "Answer": "Jim is 33 years old!" }
若要导出,事件结构中的字段名称必须大写。有关处理来自Amazon事件源的事件的更多信息,请参阅 aws-lambda-go/
有效处理程序签名
在 Go 中构建 Lambda 函数处理程序时,您有多个选项,但您必须遵守以下规则:
-
处理程序必须为函数。
-
处理程序可能需要 0 到 2 个参数。如果有两个参数,则第一个参数必须实现
context.Context
。 -
处理程序可能返回 0 到 2 个参数。如果有一个返回值,则它必须实现
error
。如果有两个返回值,则第二个值必须实现error
。有关实现错误处理信息的更多信息,请参阅Go 中的 Amazon Lambda 函数错误。
下面列出了有效的处理程序签名。TIn
和 TOut
表示类型与 encoding/json 标准库兼容。有关更多信息,请参阅 func Unmarshal
-
func ()
-
func () error
-
func (TIn) error
-
func () (TOut, error)
-
func (context.Context) error
-
func (context.Context, TIn) error
-
func (context.Context) (TOut, error)
-
func (context.Context, TIn) (TOut, error)
使用全局状态
您可以声明并修改独立于 Lambda 函数的处理程序代码的全局变量。此外,您的处理程序可能声明一个 init
函数,该函数在加载您的处理程序时执行。这在 Amazon Lambda 中行为方式相同,正如在标准 Go 程序中一样。您的 Lambda 函数的单个实例绝不会同时处理多个事件。
例 具有全局变量的 Go 函数
注意
此代码使用 Amazon SDK for Go V2。有关更多信息,请参阅 Amazon SDK for Go V2 入门
package main import ( "context" "github.com/aws/aws-lambda-go/lambda" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go-v2/service/s3/types" "log" ) var invokeCount int var myObjects []types.Object func init() { // Load the SDK configuration cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { log.Fatalf("Unable to load SDK config: %v", err) } // Initialize an S3 client svc := s3.NewFromConfig(cfg) // Define the bucket name as a variable so we can take its address bucketName := "examplebucket" input := &s3.ListObjectsV2Input{ Bucket: &bucketName, } // List objects in the bucket result, err := svc.ListObjectsV2(context.TODO(), input) if err != nil { log.Fatalf("Failed to list objects: %v", err) } myObjects = result.Contents } func LambdaHandler(ctx context.Context) (int, error) { invokeCount++ for i, obj := range myObjects { log.Printf("object[%d] size: %d key: %s", i, obj.Size, *obj.Key) } return invokeCount, nil } func main() { lambda.Start(LambdaHandler) }