我在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-HelloWorld
。 go 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作为默认选择吗?
摄