Go 中的 AWS Lambda 函数处理程序 - AWS Lambda

Go 中的 AWS Lambda 函数处理程序

Lambda 函数处理程序是函数代码中处理事件的方法。当调用函数时,Lambda 运行处理程序方法。您的函数会一直运行,直到处理程序返回响应、退出或超时。

Go 中编写的 Lambda 函数被编写为 Go 可执行文件。在你的 Lambda 函数代码中,你需要包含 github.com/aws/ /lambda 包,它实现了 Go 的 aws-lambda-go Lambda 编程模型。此外,您需要实现处理程序函数代码和 main() 函数。

例 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 函数所需的库。在此实例中,它包括:

  • func HandleRequest (ctx context.Context,event *MyEvent)(*字符串,错误):这是你的 Lambda 处理程序的签名。它是 Lambda 函数的入口点,包含调用函数时执行的逻辑。此外,包含的参数表示以下含义:

    • ctx context.Context:为您的 Lambda 函数调用提供运行时信息。ctx 是您声明的变量,用于利用通过 Go 中的 AWS Lambda上下文对象 提供的信息。

    • e@@ vent * MyEvent:这是一个指向event的名为的参数MyEvent。它表示 Lambda 函数的输入。

    • *string, error:处理程序返回两个值。第一个是指向包含 Lambda 函数结果的字符串的指针。第二个是错误类型,如果没有错误,则为 nil;如果出错,则包含标准错误信息。有关自定义错误处理的更多信息,请参阅Go 中的 AWS Lambda 函数错误

    • return &message, nil:返回两个值。第一个是指向字符串消息的指针,它是使用输入事件中的 Name 字段构造的问候语。第二个值 nil 表示该函数没有遇到任何错误。

  • func main():这是运行您的 Lambda 函数代码的入口点。该项为必填项。

    通过在 func main(){} 代码括号之间添加 lambda.Start(HandleRequest),可以执行您的 Lambda 函数。按照 Go 语言标准,开括号即 { 必须直接置于 main 函数签名末尾。

命名

provided.al2 与 provided.al2023 运行时系统

对于使用 .zip 部署包中的 provided.al2provided.al2023 运行时系统的 Go 函数,包含函数代码的可执行文件必须命名为 bootstrap。如果使用 .zip 文件部署函数,bootstrap 文件必须位于 .zip 文件的根目录中。对于使用容器映像中的 provided.al2provided.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!" }

若要导出,事件结构中的字段名称必须大写。有关处理来自AWS事件源的事件的更多信息,请参阅 aws-lambda-go/events。

有效处理程序签名

在 Go 中构建 Lambda 函数处理程序时,您有多个选项,但您必须遵守以下规则:

  • 处理程序必须为函数。

  • 处理程序可能需要 0 到 2 个参数。如果有两个参数,则第一个参数必须实现 context.Context

  • 处理程序可能返回 0 到 2 个参数。如果有一个返回值,则它必须实现 error。如果有两个返回值,则第二个值必须实现 error。有关实现错误处理信息的更多信息,请参阅Go 中的 AWS Lambda 函数错误

下面列出了有效的处理程序签名。TInTOut 表示类型与 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 函数,该函数在加载您的处理程序时执行。这在 AWS Lambda 中行为方式相同,正如在标准 Go 程序中一样。您的 Lambda 函数的单个实例绝不会同时处理多个事件。

例 具有全局变量的 Go 函数
注意

此代码使用 AWS SDK for Go V2。有关更多信息,请参阅 AWS 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) }