使用Golang作为AWS lambda功能
#aws #lambda #go #sustainability

我在XKE上被激发,做了一个简短的实验,以便将Golang用于我的AWS Lambda Functions。这是我的同事马克·范·霍尔斯泰恩(Mark Van Holsteijn)说的触发因素。我们在哪里谈论可持续性。在这次演讲中,标记发表了评论,我们应该放弃python的功能。 (他最近还使用Golang在Golang上使用Golang撰写了blog。)

让我比较Python和Go之间的一些数字。 (来源:Which Programming Languages Use the Least Electricity?))

  • 能量:75.88 vs 3.23
  • 时间:71.90 vs 2.83
  • 内存:2.80 vs 1.05

您可以看到,基于这些数字,Golang是明显的赢家。但是还有其他优势吗?因此,像往常一样,一切都带来了自己的利弊。当您选择Golang时,让我们探索这些。

预先编译的二进制与在运行时编译

让我们从显而易见的二进制二进制代码开始,然后在运行时编译。这是Golang更节能的原因之一,因为您每次运行一次都只会进行编译。但是Python的优点是您实际上可以在AWS控制台中看到源代码并调整它。这使其成为轻松开发和快速测试的绝佳候选人。这也是一个问题!当您运行生产工作负载时。您不希望开发人员通过控制台更改代码。是的,IAM可以在这里为您提供帮助,但是通过控制台无法更改二进制。

您需要编译

为什么需要汇编优势?实际上,在性能改进旁边,您实际上检查了您的程序是否编译。如果没有编译,则无法部署它。将此与Python进行比较,您可以上传错误的代码。这比因缩进问题而打破工作量。您可以在支票中构建以防止这种情况发生,您应该!但是您需要做一些额外的事情,golang这是开箱即用的。

依赖性

在Python中,您可以选择在AWS CloudFormation模板中执行内联代码。我永远不会建议这样做。当您需要其他依赖项时,就有可用的。您将需要自己捆绑并将它们上传为邮政编码。当您缺少依赖关系时,功能的调用将在运行时失败。当您使用Golang时,依赖项都将构建到二进制中。特别是当您在编译选项中设置CGO_ENABLED=0选项时。这将确保包括所有所需库。

教程

让我们部署一个小堆栈,包括一个lambda功能。我们将使用AWS SAM进行部署,因此请确保您已安装了。

准备文件结构

创建我们需要的文件夹和文件:

mkdir aws-lambda-sample-golang
cd aws-lambda-sample-golang
touch template.yaml
mkdir my-function
touch my-function/Makefile
touch my-function/main.go

SAM模板

SAM模板不再是云形式模板。但它包含AWS::Serverless-2016-10-31转换。这使您可以使用AWS::Serverless::Function资源。当云形式解析此资源时,它将转换为云形式资源。

将以下内容添加到template.yaml文件:

Transform: AWS::Serverless-2016-10-31
Resources:

  MyFunction:
    Type: AWS::Serverless::Function
    BuildMethod:
      BuildMethod: makefile
    Properties:
      Runtime: provided.al2
      CodeUri: ./my-function
      Handler: bootstrap

  MyFunctionLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub /aws/lambda/${MyFunction}
      RetentionInDays: 7

这里发生了一些事情。您可以在BuildMethod属性中看到BuildMethod设置。通过这种配置,您对SAM说要使用Makefile。此Makefile用于编译lambda函数。

  • CodeUri将指向您的lambda功能代码的根。
  • Handler将指向您的二进制输出文件。

让我们创建Makefile,我们需要将其放在函数my-function的根文件夹中。将以下内容添加到文件:

build-MyFunction:
    GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o bootstrap
    cp ./bootstrap $(ARTIFACTS_DIR)/.

这里使用的语法是build-<LOGICAL-ID-OF-CLOUDFORMATION>。因此,如果模板中的逻辑形式为HelloWorld。您的Makefile目标是:build-HelloWorldgo build命令将构建您的二进制文件。复制命令将在工件目录中复制二进制文件。部署模板时使用。

请注意GOARCH如果您使用了手臂功能,则还需要在此处指定。

lambda代码

我们需要初始化我们的GO模块,然后拉入github.com/aws/aws-lambda-go依赖性:

cd my-function
go mod init my-function
go get github.com/aws/aws-lambda-go
cd ..

现在我们可以用一些业务逻辑填充my-function/main.go

package main

import (
    "context"
    "log"

    "github.com/aws/aws-lambda-go/lambda"
)

type MyEvent struct {
    Name string `json:"name"`
}

func Handler(ctx context.Context, event MyEvent) {
    log.Printf("Welcome %s", event.Name)
}

func main() {
    lambda.Start(Handler)
}

完成!

部署模板

要部署模板,我们首先需要构建二进制文件。 AWS SAM作为支持构建和包装Lambda功能的构建。

注意:AWS SAM将在您的帐户中创建一个用于上传文物的存储桶。

sam build
sam deploy \
    --stack-name aws-lambda-sample-golang \
    --capabilities CAPABILITY_IAM \
    --resolve-s3

测试

现在,您可以使用{"name": "Joris Conijn"}有效载荷调用Lambda功能。日志现在应该显示:

欢迎Joris Conijn

对于完整的工作副本,您也可以克隆我的Nr18/aws-lambda-sample-golang存储库。

结论

对我来说,Golang将成为我对AWS lambda函数的默认选择。它是“更可持续的”,并且保护您免受明显的失败的影响,这一事实使我相信了。那个人说我有软件工程背景。因此,对我来说,切换语言相对容易。您呢,您会使用Golang作为默认选择吗?

Narcisa Aciko