程序员为什么要使用AWS Lamdba?一言以蔽之,简单。AWS Lambda和function-as-a-service平台(如Microsoft Azure函数,Google Cloud Functions和IBM OpenWhisk)通过抽象代码堆栈中的内容来简化开发。程序员编写了响应某事件的函数(如表单提交,webhook等),并将其上传,在代码执行时付费。
在《程序员请注意,无服务器将改变应用程序开发》一文中,我们介绍了FaaS运行时的工作原理以及实现无服务器的软件架构。今天,我们会通过在AWS Lambda中创建一个简单函数来展现更多事件操作,并讨论这项强大技术的常见设计模式。
在2014年的AWS re:Invent大会上,AWS首次发布了AWS Lambda。用于解释事件驱动的计算平台平台如何工作的示例如下:
将图片上传到S3存储区,触发执行Lambda功能的事件。在事件触发之前,该函数位于磁盘上的文件中,没有CPU 资源被使用,直到工作到达。一旦触发器触发,该函数将被加载到Lambda运行时并传递有关该事件的信息。在此示例中,该函数将图像文件从S3读入存储器,并创建不同大小的缩略图,然后将其写入第二个S3存储区。
下面我们就将创建实现此示例所需的Lambda代码框架,设置触发器并测试我们的代码。我们还将挖掘CloudWatch日志,以调试遇到的一些权限问题。
创建一个AWS Lambda函数并触发
创建Lambda函数有很多方法,如Eclipse插件或者是类似Serverless Framework这样的工具。这其中最简单的方法之一就是使用AWS提供的蓝图。如果我们转到AWS Lambda控制台并单击创建新功能,就会出现如下界面:
接下来使用Node.js来创建一个对S3事件作出响应的函数,所以我们从Select Runtime菜单中选择Node.js 6.10,并将S3输入到Filter 对话:
单击s3-get-object blueprint,进入“配置触发器”页面:
在这里设置用于生成事件(infoworld.walkthrough)的bucket,并将事件类型设置为在每个bucket中创建新对象时触发。接下来我们也可以进一步过滤 ,仅当存在对象名称中的某些前缀或后缀时才会触发事件。但是我们跳过该操作,并单击“下一步”按钮启用触发器。
这就创建了基于 blueprint的功能骨架:
我们把功能命名为infoworldWalkthrough,我们可以看到它会自动检索触发触发器的对象信息。
在同一配置页面下,我们需要设置一些权限:
每个功能必须分配一个IAM角色,以便我们可以控制对AWS资源的访问。这里我们要求系统创建一个名为infoworldRole的新角色,并将该角色的只读权限赋予给S3。如果我们要实现完整的规范示例并生成缩略图,我们还要添加S3写入权限。但是,由于我们只需读取有关触发S3对象的信息,所以只读权限应该是足够的。
最后,我们需要注意一些高级设置:
最重要的工作是我们要设置内存量和执行超时的上限。请记住,Lambda运行时借鉴了容器的流水线,它们预装了各种语言运行时。当一个事件触发它会将代码加载到这些容器中,并执行功能。内存和超时设置决定了容器将有多大,以及我们的功能需要执行多少时间。在这个示例中,默认值设置为128MB和3秒比较好。如果是其它示例,可以根据自己的需求来更改默认值。
点击“Next”进入到另一个页面,来查看我们目前为止所有输入的设置:
点击“创建函数”按钮在AWS Lambda中创建函数。
检查我们的AWS Lambda代码
以下是blueprint为我们创建的默认代码:
在第14和15行,Lambda函数提取了bucket的名称和触发触发器的对象名称(也称为键)。然后使用S3 API获取有关对象的更多信息,(如果顺利)输出其内容类型。虽然我们在这里没有这样做,但是我们可以很容易地包含,然后读取对象的代码,并相应地生成缩略图。
测试我们的AWS Lambda代码
现在让我们来到S3控制台来解决这个问题,在这种情况下,bucket最开始是空的:
我们将InfoWorld徽标的PNG上传到该存储区:
从S3 控制台还无法看出函数是否被执行,即使访问Lambda控制台,也无法完全获得。每个Lambda函数都通过CloudWatch记录信息,所以如果我们检查CloudWatch,就会看到有一个函数的新日志组。
检查该日志,其显示访问S3 bucket 被拒绝:
当我们的代码尝试读取S3对象的信息时,被拒绝访问数据。为什么呢?是因为我们没有设置IAM角色,以便我们的函数在S3 bucket上具有只读权限吗?我们需要在IAM控制台上仔细检查一下:
没错,这个角色有一个策略,我们来看一下:
我们有权在CloudWatch中创建日志,但是S3只读权限策略不知为何没有被采取。点击附加策略按钮之后,我们会看到下方界面:
通过选择AmazonS3FullAccess选项并按附加策略按钮,为函数添加所需的权限。通过手动将PNG文件添加到S3 bucket中来测试功能:
现在,如果我们按测试按钮,我们将得到一个对话框,让我们从许多示例事件中进行选择。我们要测试S3 put。我们需要编辑S3 key和bucket名称字段中的值,分别对应于我们的图像文件和存储bucket的名称:
事件中各种各样的其他字段也可以在这里设置,但是由于我们的代码仅查看关键字和bucket名称,所以先暂时忽略其余的字段。按保存和测试按钮将触发事件并执行函数。与上一次不同,当通过S3控制台触发事件时,我们看到了现场反馈。我们还可以在Lambda UI中获取CloudWatch日志的相关部分:
您可以看到我们的代码执行并按预期标识了内容类型。
IDE集成和命令行工具(如Serverless Framework)能够显著加速此过程,但是这次演示显示了通过CloudWatch创建具有正确权限,设置事件和调试代码的功能以及两种不同的方式触发事件,以便可以测试该功能。
我们来看看一些常见的Lambda设计模式。
AWS Lambda设计模式
针对无服务器应用程序架构出现了许多设计模式。AWS re:Invent上“ 无服务架构模式”和“最佳实践 ”的会议上强调了四个模式。接下来,我会介绍两个自己很喜欢的模式,因为它们适用于刚刚开始使用无服务器架构!
首先,构建Web应用程序,使用S3和CloudFront进行静态内容,使用由Lambda和DynamoDB支持API网关的动态需求:
这种基本模式可以在多个级别的安全性下紧密锁定:
Web应用程序的大部分内容对于用户来说是只读的,并且可以从S3和CloudWatch获得此模型。授权数据可以利用IAM hook API网关以及与DynamoDB进行交互的单个Lambda函数的IAM角色。
我第二个最喜欢的用例 - 由Capital One为其Cloud Custodian项目实施 - 是使用Lambda设置自动化hook。 在Capital One的实施中,CloudWatch日志事件触发Lambda函数,以针对Capital One特有的合规性和策略规则执行检查。 当发现潜在问题时,该功能将通过Amazon SNS生成通知,可通过Amazon SNS配置发送短信,电子邮件和其他一些机制,以便向正确的人员发出需要注意的违规策略。
我喜欢这种自动化模式,因为它为现有流程增加了巨大的价值,而不会以任何方式扰乱该流程。系统合规性是自动化的,而不会触及被监控的系统。
更多思考
如我们所见,设置Lambda功能,配置事件,应用安全策略和测试结果是一个没有IDE或命令行工具的快照。 Microsoft,Google和IBM为他们的FaaS运行时提供了类似的轻松onboarding功能。 加上设计模式的出现,这无疑将为更高级的工具和重用铺平道路。
无服务器应用程序体系结构表现出非常不同的心态。 代码段较小,仅在触发时才执行,降低了成本,并通过松散耦合的事件而不是静态定义的API绑定在一起。 无服务器可以实现比之前可能更快的开发周期,并且利用简单的自动化和Web应用程序设计模式,风险更低。
本文作者:田晓旭
来源:51CTO