带您玩转Lambda,轻松构建Serverless后台!

2019 年 11 月 18 日

带您玩转Lambda,轻松构建Serverless后台!

Amazon CTO Werner Vogels 曾经在 AWS re:Invent 大会上提到: 如果把云计算理解成一个执行环境,那么,在这个环境里,函数(即业务逻辑的载体)+数据(即跟业务相关的输入与输出)就是应用的核心,有了 Functions、Data、Event 这三者,其它任何代码和框架,无非是整个应用的胶水和 UI 罢了。那么,最理想的情况就是用最少的时间写胶水,将更多的时间投入到核心应用的开发中,甚至,彻底实现整个软件栈的微服务化。


那么能不能做到呢?答案是肯定的。AWS Lambda 也在这样的背景下应运而生了,其实在很多人眼里,Lambda 是一个具有“革命性”的服务,我本人也非常喜欢 Lambda 这个服务,因为它给我的感觉是: 轻、快、高可用!能够快速将想法写成代码,并应用到生产,不需要关心底层基础设施的运维。接下来,让我们一起搭建一个 serverless 的后台!


【1】AWS Lambda 怎么用?


怎么学习 Lambda 呢?让我们从一个简单的数学问题开始,10 以内乘法和加法运算,获得随机的一个数字。代码有注释,如下:



//Node.js尽量全使用严格模式


'use strict';


//利用console.log可以将日志自动打到CloudWatch里面


console.log('Loading function');


exports.handler = (event, context, callback) => {


//定义一个最小值为2


var min = 2;


//定义一个最大值为10


var max = 10;


//生成一个随机数,乘以最大值,再加上一个最小值


var generatedNumber = Math.floor(Math.random() * max) + min;


//利用callback回调,得到结果。


callback(null, generatedNumber);


};


接下去,然后选择 Lambda 服务



创建一个 Lambda Function



选择 Node.js 6.10 的环境



当然,Lambda 目前支持 C#,Node.js,Python,Java,后续会支持很多的语言比如 Go,PHP,Ruby 等。换言之,之后任何能在 Linux 上跑的环境都能在 Lambda 上运行。



接下去把上面那段代码拷贝进去,选择“Role”角色,这其实就是 Lambda 执行时所拥有的权限。当然,你可以通过 IAM 服务创建一个新的 Role,或者选择已经存在的 Role。



然后点击“Create Function”,接着就会看到



好!Lambda 创建成功了!在 Lambda 上方点击 Test,进行测试,能看到输出的结果。细心的你已经发现,代码运行的时间只有 0.3ms 哦。



查看 Lambda 执行的结果:



您可以多次点击 test,每次输出的结果都不一样,这是因为,代码一开始生成了一个随机数,所以每次输出的结果也都是随机的。



您可以点击“View logs in CloudWatch”,能看到所有 Lambda 运行相关的日志。AWS 已经把这部分的日志已经自动集成到 CloudWatch 里面了。




如果你想结合自己常用的日志分析工具,比如 sumologic,可以再用一个 Lambda 将 CloudWatch Logs 的日志导出。



【2】Lambda + API Gateway


到这里,我们发现,应用的逻辑可以交给 Lambda 执行,那前端的 HTTP 请求怎么办呢?AWS 还有一个服务叫 API Gateway,提供的 HTTP 网关服务,那么,Lambda 怎么和 API Gateway 又怎么结合起来使用呢?


接下去,您可以进入到 API Gateway 这个服务里面,点击“Create API”。



写入 API 的名字然后创建



创建一个 Method



选择 HTTP Get 方法。目前,AW API Gateway 支持 HTTP DELETE, HEAD, OPTIONS, PATCH, POST, PUT 等方法。指定我们之前创建的 Lambda 函数,选择“Integration Type”Lambda Function。



输入 Lambda 对应的 Region 和 Lambda 函数的名字,然后点击 Save。



然后进行部署 API,点击“Deploy API”。



指定 API 的版本,比如 prod 或者 test。



注意,当你定义好这个 API 之后,可以自动生成整套 SDK,有 Android,JavaScript,iOS-OC,iOS-Swift,Java。所以,开发人员可以基于这一套自定义的、标准的 SDK 进行统一开发。只要指定了统一的后端数据库,所有的开发人员都可以各自开发自己的内容,互不干扰,最终形成一个统一、完整的项目。



然后点击“Stages”,查看 Get 的 http 地址。



将这个地址复制到浏览器(比如 Firefox),可以查看 Lambda 运行后输出的结果。这样,Lambda 就和 API gateway 结合起来了。



点击刷新,当然数字会变。


【3】Lambda + API Gateway + 传参


如果客户端需要想传递参数,怎么办呢?


那就可以通过 API Gateway 接受客户端(比如浏览器)输入的参数,然后 API Gateway 把这个参数传递给后端的 Lambda,Lambda 通过 event 对象获得前端 API Gateway 传递过来的参数,从而进行代码的逻辑执行。


让我们先改动一下 Lambda 的代码,将固定值 2 和 10 换成以变量的形式传递进去。



然后再到 API Gateway 服务里面,找到“Integration Request”。



找到“Body Mapping Templates”,修改其中的“application/json”,输入提供的内容。



{


"min":$input.params('min'),


"max":$input.params('max')


}


点击保存,这样,就通过客户端就可以把参数传递给 API Gateway 了。比如:


https://j3bi4vs4w4.execute-api.us-west-2.amazonaws.com/prod/number


这个时候打开之前的链接是空值,因为还没传递参数进去。



https://j3bi4vs4w4.execute-api.us-west-2.amazonaws.com/prod/number?min=1&max=10


在浏览器客户端中,传递参数进去之后,比如 min=1,max=10,如下:



刷新浏览器,当然会得到随机的结果。



再来一次,刷新浏览器,当然会得到随机的结果。



【4】快速部署 Lambda 函数?


部署 Lambda 的函数,可以直接在控制台输入代码,也可以在本地写好之后打成 zip 包上传到 Lambda,或者上传到 S3 再指定链接内部加载到 Lambda 上。


当然,如果觉得不是很方便,目前其实已经有很多开源的框架支持都 Lambda 的快速部署了,比如 SERVERLESS.com,Claudiajs.com,APEX,Zappa,Kappa,Chalice 等。



【注意!】我们会在下一期内容中专门讲解这些框架怎么用,以及如何借用这些框架,再配合 AWS CodePipeline,CodeCommit,CodeBuild,CloudFormation 完全实现 serverless 微服务化,一键自动化发布和部署整个软件栈。


在这里,由于个人喜好,我们拿一个比较轻量的工具 APEX 举例,http://apex.run/,Apex集成了Lambda的SDK,用户只需要在本地执行apex init 命令就创建了一个 Lambda 环境以及所需的 Role,然后通过 deploy 命令就可以将本地的 Lambda 代码以及所需要的依赖自动打成 zip 包,并上传到云端环境。并且 Apex 会自动进行 Lambda 版本管理,更重要的是,还支持回滚,查看云端 log。这可以让您真正只关心代码,写完代码之后直接部署就可以了,非常方便。你会发现,开发的时候甚至连 AWS 的控制台都不需要打开!



本地安装,一条 curl 语句。搞定了!真的挺简单的。


curl https://raw.githubusercontent.com/apex/apex/master/install.sh | sudo sh


接下去通过 aws configure 配置你的权限


danrongm:~ danrong$ aws configure


AWS Access Key ID [****************2T5A]:


AWS Secret Access Key [****************Tcma]:


Default region name [us-west-2]:


Default output format [json]:


创建 apex 项目: apex init,然后输入项目名称 first-apex-project



接着就开始部署了


acbc32c13f31:apex-demo danrongm$ apex deploy


• creating function env= function=hello


• created alias current env= function=hello version=1


• function created env= function=hello name=first-apex-project_hello version=1


Apex 自动会帮您创建 Role,以及进行版本的管理和控制。当你修改完代码之后,可以再次执行 apex deploy,只要代码有改变,版本号以数字形式就会往上增加。


如果部署其中的一个函数: apex deploy hello


如果调用函数显示输出结果: apex invoke hello


另外,可以直接在本地查看日志的输出。


**apex-demo danrongm$ apex invoke -L hello 会把日志输出的所有内容输出**


START RequestId: 7c432478-ee78-11e6-8d9b-21a4e48977b8 Version: 5


2017-02-09T03:33:13.014Z 7c432478-ee78-11e6-8d9b-21a4e48977b8 processing event: {}


END RequestId: 7c432478-ee78-11e6-8d9b-21a4e48977b8


REPORT RequestId: 7c432478-ee78-11e6-8d9b-21a4e48977b8 Duration: 0.41 ms Billed Duration: 100 ms Memory Size: 128 MBMax Memory Used: 10 MB 104


查看 Apex 的所有日志(其实就是最近 5 分钟内的 CloudWatch 的日志)


apex logs


【5】Lambda + CloudWatch Event


有些场景,有可能是想定期、或者定时让 Lambda 去执行处理逻辑,针对这种情况,可以使用 CloudWatch Event,触发 Lambda 定时执行。



可以在 CloudWatch 里面创建一个 Rule,然后 Event selector 可以通过 Cron 方式定期调用 Lambda 函数,如下:



这样,你就可以按照一定的规则,定时的去触发 Lambda 函数了。更多内容可参考:


http://docs.aws.amazon.com/zh_cn/AmazonCloudWatch/latest/events/RunLambdaSchedule.html


【6】Lambda + DynamoDB –> 数据写入到数据库


用户发送 HTTP 请求,交给 API Gateway 处理,业务逻辑交给 Lambda 处理,那如果动态的数据需要存储到数据库呢?AWS 提供了 NoSQL 的数据库 DynamoDB 和关系型数据库 RDS,这些都可以和 Lambda 配合使用。值得一提的是,Lambda 可以和 RDS 一样,放在 VPC 内部,配置安全组。


那么,如何使用 Lambda 把处理后的数据存储在 DynamoDB 呢?Lambda 又怎么和数据库进行交互呢?直接上代码。首先创建一个 Lambda 函数,比如命名为: lambda_dynamodb_write,代码如下



'use strict';


console.log('Loading function');


var AWS = require('aws-sdk');


var docClient = new AWS.DynamoDB.DocumentClient();


AWS.config.region = 'us-west-2’;


exports.handler = function (event, context, callback){


var params = {


Item: {


date: Date.now(),


message: "Danrong"


},


TableName: 'lambda_dynamodb_write_read'


};


docClient.put(params, function(err, data){


if(err){


callback(err, null);


}else{


callback(null, data);


}


});


};


【7】Lambda + DynamoDB –> 数据从数据库读取


搞定了数据库的写入操作,Lambda 又怎么读写数据库里的内容呢?直接上代码。


创建一个 Lambda 函数,比如命名为: lambda_dynamodb_read,代码如下



'use strict';


console.log('Loading function');


var AWS = require('aws-sdk');


var docClient = new AWS.DynamoDB.DocumentClient({region:'us-west-2'});


exports.handler = function(event, context, callback){


var params = {


TableName: 'lambda_dynamodb_write_read',


Limit: 100


};


docClient.scan(params, function(err,data){


if(err){


callback(err, null);


}else{


callback(null, data);


}


});


};


对于数据库的修改和删除操作,同样可以轻松做到。到这里,Lambda 和 DynamoDB 的交互就搞定了。


【8】Lambda + API Gateway + DynamoDB


此时,我们再将前面三者,即 Lambda,API Gateway,DynamoDB 结合起来。创建一个 Date 为主键的 DynamoDB Table,让它存储 Lambda 处理的结果,如下:



由于之前我们已经创建过 HTTP GET 了,同样的方式,在 API Gateway 里面,创建一个 HTTP POST 的方法。如下:



API Gateway 中可以解决跨域 CORS 的问题,点击“Enable CORS”。



到这里,客户端浏览器发出请求,会发送到 API Gateway 那边,然后 API Gateway 传递客户端的参数给 Lambda,Lambda 通过 Event 对象获取 API Gateway 传参的值,并处理逻辑。比如将数据写入到 DynamoDB,或者从 DynamoDB 读取数据显示在前端。


【9】Lambda + API Gateway + DynamoDB + S3 + CloudFront


托管静态网站。如果您是一个网站,或者是移动、IoT 等后台,可以把前端显示的静态内容,比如 HTML,JS,CSS,以及所有图片托管在 S3 上,启用静态网站托管。


到这里,一个 serverless 的网站就做好了,您可以点击下面链接进行尝试。


https://s3.amazonaws.com/danrong.io/index-ajax.html



前端显示的 HTML 代码开源,您可以公开下载:


https://s3.cn-north-1.amazonaws.com.cn/danrong-share/external/aws-china-blog-lambda-demo-index.html


接下去,其实就是前端的 UI 设计了,比如,我比较喜欢用http://www.bootcss.com/


完全可以改善一下前端的展示风格,看起来舒服一点。



如果要解决域名的问题,可以使用 Amazon Route53 访问(注意,域名也可以直接在 Route53 上购买),这样,就可以用您自定义的域名访问一个 Serverless 的网址了。



到这里,一个类似于“点击发布评论”、“查看所有评论”的网站就完成了。整个网站基于微服务的思想,完全实现了 serverless 的架构。


【10】Lambda + CodeCommit + CodePipeline + CodeBuild + CloudFormation


到这里,或许您已经在考虑 Lambda 如何做到持续化的发布和部署呢?能不能让我的开发人员只关心写代码,其余之后的事情全部一键搞定呢?比如,开发人员在本地用各种各样的 IDE 写代码,写完之后将代码提交到 Git 仓库,然后整个 pipeline 自动完成。在 AWS 的世界里,当然可以!例如,整个流程可以这样:



我们完全可以利用 AWS 全面的开发工具,CodeCommit + CodePipeline + CodeBuild + CloudFormation,实现从代码开发,到代码提交,到代码发布,到代码构建,到代码部署,一键自动化发布整个软件栈。再配合 Serverless 的各种框架(见前面正文),真正可以做到微服务化并且快速迭代敏捷开发!


另外,读者也可以关心一下 Security 安全的问题,比如 Authentication, Authorization, Sensitive data 等问题;关于 Quality,比如 Testing, Continuous Integration, Deployment 等问题。这两部分的内容,我们将会在下一期中介绍,期待您继续关注 AWS 中国官方微信。


更多关于 Lambda 内容可以参考:


https://aws.amazon.com/cn/lambda/


http://docs.aws.amazon.com/zh_cn/lambda/latest/dg/welcome.html


作者介绍:



毛郸榕


AWS 解决方案架构师,负责基于 AWS 的云计算方案架构的咨询和设计,同时致力于 AWS 云服务在国内的应用和推广,毕业于北京航空航天大学云计算专业,硕士,毕业后直接加入亚马逊 AWS 中国。在大规模后台架构、企业混合 IT 和自动化运维等方面有着丰富的实践经验。目前在集中精力学习新一代无服务器架构的开发与设计。


本文转载自 AWS 技术博客。


原文链接:


https://amazonaws-china.com/cn/blogs/china/lambda-serverless/


2019 年 11 月 18 日 08:00260

欲了解 AWS 的更多信息,请访问【AWS 技术专区】

评论

发布
暂无评论
发现更多内容

初步架构想法

极客大学架构师训练营

架构师训练营第一周 - 学习总结

Eric

极客大学架构师训练营

Hello World!

东哥

极客大学架构师训练营

第一周总结

LEAF

架构师训练营 No.1 周作业

连增申

解决出海网络难题 融云保障 MiniJoy 千万印度用户流畅互动

Geek_116789

食堂就餐系统设计

Hugo

聊聊Java中的Thread类

geekymv

线程 Java25周年 Thread Runnable

老当益壮的 Servlet

侯树成

Java Java 25 周年 Servlet

架构师训练营-学习总结-第一周

ashuai1106

学习 架构师 极客大学架构师训练营

第二章.软件架构设计

西柚

架构师训练营第1周_学习总结

chinsun1

架构总结

架构课程心得

dj_cd

极客大学架构师训练营

食堂就餐卡系统设计

LEAF

week01 UML 学习总结

李锦

低调的网易又要上市了

池建强

创业 网易 慢公司

架构师训练营-作业-第一讲

吕浩

极客大学架构师训练营

架构师训练营作业一:食堂就餐卡系统设计

sunnywhy

架构师训练营第一周(总结)

任鉴非

架构师作业一:食堂就餐卡系统设计

李锦

第1周 - 学习总结

大海

剖析Golang Context:从使用场景到源码分析

伴鱼技术团队

golang 源码分析 并发编程 程序语言 Context

食堂就餐卡系统设计

Kiroro

架构建模总结

任鉴非

食堂就餐卡系统设计

于成

为什么建立自己的规则很重要

Neco.W

自我管理 行动派 执行力

8000字长文让你彻底了解 Java 8 的 Lambda、函数式接口、Stream 用法和原理

古时的风筝

函数式接口 Lambda stream Java 25 周年

食堂就餐卡系统架构设计

dj_cd

极客大学架构师训练营

架构师训练营第一课

于成

架构师训练营第一周总结

Kiroro

架构师训练营第一周总结

Hugo

带您玩转Lambda,轻松构建Serverless后台!-InfoQ