FaaS(Fuction as a Service)函数即服务,它提供了一个平台,允许我们运行某些程序功能,而无需构建和维护程序所依赖的软硬件环境。FaaS很适合作为API服务的实现方式,本系列文章将从PT-Gen这一项目入手,按照TDD的方式,简单介绍如何将现有的项目迁移到FaaS上。
介绍
我们先来说说PT-Gen这个项目,这个项目脱胎于@Rhilip的PT-help,其主要功能是将豆瓣等链接的信息提取出来,转变为PT站点可用的简介形式,因其简单好用而广为人知。
说回PT-Gen本身,从PT-help抽离之后,@BFDZ使用flask将PT-Gen的功能独立出来,同时将查询结果的数据库缓存转为依赖sqlite,大大降低了部署成本。但是即使是这样,也需要api的提供者有着基本的Web Server知识以及对服务器的维护能力,@YeZi在部署的过程中就遇到了这样或那样的困难。
于是,无需运维的FaaS就变成了这样一种场景下的最佳选择。
工具的选择
AWS提供了一整套的SDK,并在Lambda上给出了在线IDE,但是对于现有项目的迁移,我们完全不需要重新编写Handler,我们使用另一个工具serverless帮我们解决迁移问题。事实上,类似的工具还很多,例如Zappa、Claudia.js等等,但是在前期准备的过程中,发现这些工具虽然简单好用,但是在后期对于函数本身更细节的行为操控上缺乏了应有的直观简洁,故最终选择了serverless。
serverless是用nodejs写就的,但是这并不妨碍基于Python项目的部署,而且serverless提供了极为强大的插件功能,能让并不直观的FaaS开发变的简单有效,我们稍后就会见到。serverless的安装也非常简单,只要你配置好了nodejs和npm,然后
npm install -g serverless
即可将serverless安装到全局,我们可以在bash环境中设置一个alias,将命令缩写为sls。
从现有项目迁移
flask作为Python写API的首选架构,迁移起来的难度非常低。这里要注明一点,FaaS只在被调用的时候运行,而且运行完成之后所有的数据都会被销毁,这意味着sqlite这样最终会被储存到文件中的缓存并不会起作用。在熟悉FaaS的这一阶段,我们可以先放弃这一缓存过程,把重点放在sls的使用上。
任何一个FaaS都必须有一个handler。在serverless中,我们可以通过 serverless-wsgi
插件,将app.py中的app转化为handler。接下来是我们需要 import
的各种库文件需要打包上传,因为在FaaS的环境中,只包含了基础的Python库,我们可以通过 serverless-python-requirements
将库文件打包上传。
serverless使用YAML作为配置文件的格式,我们需要将 serverless.yml
放在项目的根文件夹之下,大致的样子如下
service: ptgen
provider:
name: aws
runtime: python3.6
stage: dev
region: ap-southeast-1
memorySize: 512
plugins:
- serverless-wsgi
- serverless-python-requirements
custom:
wsgi:
app: app.app
packRequirements: false
functions:
app:
handler: wsgi.handler
events:
- http: ANY /
- http: 'ANY {proxy+}'
这样,我么就通过这一配置文件,指定了服务名称、运行环境以及handler的入口
如果你的API没有类似缓存一样的功能,只是简单的IO或者计算处理,这里可以直接在根目录下使用
sls deploy
就可以将整个函数部署,此时,serverless会自动帮你把代码中的库打包为压缩文件并上传到S3中,并返回一个 endpoint_url
。
这样,我们就得到了自己的第一个FaaS。
Tips
如果你对自己的项目没有十足的把握,serverless提供了本地的测试环境,只需要
sls wsgi serve
这样就会在本地运行模拟的Lambda环境,Debug非常方便。这里需要注意的是,这一功能在Windows下并不完善,建议还是在Linux和MacOS上进行FaaS的相关开发。
部署之后如果遇到了
Internal Error
,我们可以通过AWS CloudWatch查看log,也可以直接在命令行中输入sls logs -f app
由于我的API已经调试完毕,这里没有可以展示的。
AWS Lambda给每个账户提供了每个月400000GB-秒和100万次请求的免费套餐,这对于一般的项目原型来说可以说是绰绰有余的。但是需要指出的是,随着内存的减少,CPU的最高频率也被限制,这一点AWS Lambda并没有标明,但是在GCP中有很明确的标识。
对于PT-Gen这样的项目来说,512MB内存对应的CPU资源,能够使得函数在6s内冷启动并刮削完成所有的数据,当然有省钱的办法,这一点我们后续文章详细说
- 通过指定不同的stage,我们可以将不同的开发分支区分开来,这对于FaaS这样TDD模式非常有用