无服务器(Serverless)对开发人员来说应该是非常友好的架构,无须管理底层物理资源,操作系统配置、打补丁、弹性伸缩的配置统统不需要去操心了,只要专注在代码开发上,其他杂活都可以交由无服务器架构来完成,因此无服务器的应用自然更为流行
今天跟一个客户交流时他提到的一点我也感同深受:开发人员就是想要爽,代码写完一条命令可以在本地做调试,调试完一条命令可以直接把代码部署上去,爽!由于无服务器架构的特点,如果不在本地构建开发测试环境,每次都需要部署到云端再做调试,会非常不爽。另外自己打包代码,然后再手动上传到云端部署和配置也是非常繁琐。
最近研究了在AWS Serverless本地开发测试和部署相关的工具,包括AWS原生提供的开源工具AWS Serverless Application Model(SAM)和第三方Serverless.com提供的开源工具Serverless Framework Open Source 。充分感受到了部署和调试工具带来的爽!两个工具各有特色,其本质都是通过一个简化语法的模板文件(yaml),让用户来定义无服务器架构配置的一些细节,然后由工具自动对代码进行打包(包括安装相应的依赖包), 自动将该模板转换为一个Cloudformation的标准模板(相信我,Cloudformation模板不是给人看的,是给机器看的!) ,最后再将模板部署在AWS上面。如果有配置变更或代码变更,同样也由该工具重新打包上传代码,并利用Cloudformation的机制来进行整个配置的更新。
另外除了自动部署,这两个工具都提供了本地调试的方法,可以方便开发人员在自己电脑上把lambda代码跑起来,甚至可以在本地模拟api gateway,开发调试感觉就更爽了。
接下来就一起来尝试一下Serverless Framework:
安装
Serverless Framework提供了一个CLI工具(基于Node.js), 在本机安装好Node.js后,通过如下命令可安装Serverless Framework:
$ npm install -g serverless
初始化项目
通过如下命令创建一个基于python3模板的项目:
$ sls create --template aws-python3 --path sls-lambda-python3
Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "/Users/linjungz/projects/sandbox/sls-lambda-demo/sls-lambda-python3"
_______ __
| _ .-----.----.--.--.-----.----| .-----.-----.-----.
| |___| -__| _| | | -__| _| | -__|__ --|__ --|
|____ |_____|__| \___/|_____|__| |__|_____|_____|_____|
| | | The Serverless Application Framework
| | serverless.com, v1.67.3
-------'
Serverless: Successfully generated boilerplate for template: "aws-python3"
模板配置
修改serverless.yml,指定AWS上部署的一些配置细节,包括部署的区域,命令行使用的profile等。如果不修改模板文件,也可以在部署时通过命令行参数提供。
provider:
name: aws
runtime: python3.8
# Lambda部署的AWS区域
region: cn-northwest-1
# AWS CLI Profile
profile: cnlab
functions:
hello:
handler: handler.hello
# 在API Gateway中配置 HTTP API 来触发Lambda
events:
- httpApi: 'GET /'
修改handler.py:
import json
def hello(event, context):
body = {
"message": "Hello World AWS Serverless"
}
response = {
"statusCode": 200,
"body": json.dumps(body)
}
return response
部署与调试
接下来就可以进行部署:
$ sls deploy
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
........
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service sls-lambda-python3.zip file to S3 (390 B)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
..............................
Serverless: Stack update finished...
Service Information
service: sls-lambda-python3
stage: dev
region: cn-northwest-1
stack: sls-lambda-python3-dev
resources: 11
api keys:
None
endpoints:
GET - https://9ea7dptou3.execute-api.cn-northwest-1.amazonaws.com.cn/
functions:
hello: sls-lambda-python3-dev-hello
layers:
None
Serverless: Run the "serverless" command to setup monitoring, troubleshooting and testing.
可以看到lambda已经部署到AWS上,同时配置了API Gateway HTTP API,接下来可以测试一下这个接口:
$ curl https://9ea7dptou3.execute-api.cn-northwest-1.amazonaws.com.cn/
{"message": "Hello World AWS Serverless"}%
查看Lambda执行的日志:
$ sls logs -f hello
START RequestId: 11a21905-0c6b-453d-8386-6367e99494fa Version: $LATEST
Debug: {'message': 'Hello World AWS Serverless'}
END RequestId: 11a21905-0c6b-453d-8386-6367e99494fa
REPORT RequestId: 11a21905-0c6b-453d-8386-6367e99494fa Duration: 1.34 ms Billed Duration: 100 ms Memory Size: 1024 MB Max Memory Used: 53 MB Init Duration: 697.87 ms
修改代码中变量body的值,并在本地进行运行查看结果:
$ sls invoke local -f hello
Debug:
{'message': 'Hello World AWS Serverless V2'}
{
"statusCode": 200,
"body": "{\"message\": \"Hello World AWS Serverless V2\"}"
}
可以看到本地运行结果已经更新,这时候使用 sls deploy
命令重新可以部署到云上并查看到返回结果已经更新。
使用 serverless-offline 插件进行本地调试
接下来我们尝试搭建本地的API Gateway + Lambda 的调试环境,需要安装Serverless Framework的一个插件: serverless-offline
$ sls plugin install --name serverless-offline
Serverless: Creating an empty package.json file in your service directory
Serverless: Installing plugin "serverless-offline@latest" (this might take a few seconds...)
Serverless: Successfully installed "serverless-offline@latest"
该命令会自动修改 serverless.yml
文件以启用这个插件
plugins:
- serverless-offline
接着通过如下命令启用本地调试
$ sls offline
offline: Starting Offline: dev/cn-northwest-1.
offline: Offline [http for lambda] listening on http://localhost:3002
┌─────────────────────────────────────────────────────────────────────────┐
│ │
│ GET | http://localhost:3000/dev │
│ POST | http://localhost:3000/2015-03-31/functions/hello/invocations │
│ │
└─────────────────────────────────────────────────────────────────────────┘
offline: [HTTP] server ready: http://localhost:3000 🚀
offline:
offline: Enter "rp" to replay the last request
查看本地运行的结果:
$ curl http://localhost:3000/dev
{"message": "Hello World AWS Serverless V2"}%
同时可以看到sls offline
也会实时显示相关的日志:
offline: GET /dev (λ: hello)
Debug: {'message': 'Hello World AWS Serverless V2'}
offline: (λ: hello) RequestId: ck93gtjk40008ebs5dikdcq2m Duration: 359.61 ms Billed Duration: 400 ms
从上面的简单测试可以看到,Serverlss Framework在模板配置上相当精炼,同时本地调试也非常方便,关键CLI还是开源的,有非常多的plugin进行功能扩展,真是无服务器开发与部署的利器!
本文所使用的代码可参考如下链接: github.com/linjungz/sl…
注:观点仅代表个人