本文是从项目工程角度来讲解的,技术角度请参看另一个文章《真实项目代码教你四步扔了传统服务器,让你优雅使用Serverless做全栈开发》(https://zhuanlan.zhihu.com/p/...)
本文汇总了我的多个Serverless的全栈项目实际开发的经验,主要针对中小型项目。可以直接使用我的经验,或者根据实际情况再做调整。
第一步:决策Serverless
项目管理的艺术体现在如何在限定条件下发挥优势、规避劣势,因此我们需要先确定中小项目里Serverless的优劣势是什么。
(一)Serverless的优势
- 成本低:对小项目来说,Serverless的成本可以说极其低,虽然我们技术人员不太关心和负责成本,但是对于中小项目的公司级决策来说,成本是一个无法规避的问题。
- 低人员需求(专注开发):不再需要对服务器环境进行配置、管理和优化了,代码直接上传即可使用。
- 颠覆式的性能优化(性能就是这么方便):这个是我最看重的优势,也是必须发挥的优势。传统服务器的调优配置是针对全项目级的,一个接口出现性能瓶颈需要拉动整个项目的配置,而Serverless可以做单个API接口级的性能优化,比如我们可以只提高首页、热门活动的性能配置。这是其他传统项目需付出较高的开发代价才能做到的,而Serverless极其轻松的就可以实现。
- 安全:Serverless因其独特的特点,注定其安全也和传统安全有很大不同。当前主流网络攻击如系统入侵、DDos攻击等方式对Serverless大多并不生效甚至直接失效,也尚未发现专门针对Serverless的攻击工具,加上Serverless本身提供了一些安全机制,比如腾讯云SCF的单函数的独占配额、全函数的共享配额、API网关鉴权等,合理的使用后可以低成本实现高安全性。
(二)Serverless弊端:他的弊端需要生态来解决
- 实践少:Serverless虽然2014年就出来了,但是真的被用起来感觉是这三四年的事,使用也以高大上的项目或个人自己玩票为主,全栈项目更是少了。同时,有实践经验的人员又缺乏布道的时间和渠道,市面的书籍也以理论为主。因此行业内尚无成熟的、权威的工程理论来指导Serverless的 DevSecOps,这就对项目经理自身提出了更高的要求,甚至对项目经理是否可以准确评估风险和大胆决策提出了额外要求。
- 框架少:现在还没有Serverless原生框架。
- 部署麻烦:不用多说,这个是硬伤,但也是最好解决的。如同10多年前的JavaScript突然兴起后出现的jQuery等框架,Serverless的弊端就是开发者的机会,大胆尝试率先寻找出解决之道的也将引领Serverless。
第二步:项目方案选型
(一)云服务商选择
项目开始前,我们要选用服务商。市面上Serverless服务商很多,到底选哪个服务商,是所有项目负责人要做的第一个择决。其实对于大型服务商来说,选哪个都可以的,我个人是腾讯云的云函数深度使用者(所以别问我,问就是推荐腾讯云),因此本文的经验也是建立在腾讯云基础上,当然每个平台的调优等有一定的差异,但殊途同归,完全可以借鉴的。
(二)云函数选型
腾讯云的云函数分两大类“WEB函数”和“事件函数”,然后每个大类部署方式有“镜像部署”和“代码部署”,对于中小项目来说,我推荐“事件函数”+“代码部署”。
WEB函数:在我看来“WEB函数”是为了扩展云函数的市场占有率而硬搞出来东西,甚至在开始的时候,云函数根本就没有这个“WEB函数”,是最近一两年才有的。
厦门量潮科技有限公司的创始人兼CEO张果(知乎iGuo)也提到“WEB函数”其实就是一种妥协。
WEB函数是将整个项目集合在一个云函数里面进行部署, 这会让我们无法发挥Serverless的“接口级管理”和“安全”两大优势,丧失了Serverless最大的特性,而仅得到了“框架支持”这个功能,是非常不划算的。其实框架支持在Serverless中其实对中小项目来说并不重要,甚至是可有可无,详见下面说明。
部署方式的选择:
代码部署就是直接将代码部署到云上。镜像部署是将项目在本地制作成镜像后上传到腾讯云的“容器镜像服务”,再推送到云函数中。
其实腾讯云内置的各项扩展已经满足大部分的项目技术需求了,部分没有直接内置的也可以自己通过第三方包直接实现,除了要求很复杂的项目外,代码部署已经满足大多数项目的需求了。
“代码部署”的方式让云上和本地保持了高度一致性,甚至云上问题本地可以快速、简单的还原,同时部署操作简单、维护便捷、速度快、性能好、本地或云上调试方便。
因此建议:尽量在“代码部署”确实不能满足项目需求的时候才使用“镜像部署”。
我认为:Serverless应用的极致体验是本地 hello world式开发,就等同于项目开发。
第三步:框架选择
以PHP为例,中小项目使用Serverless,传统的框架很可能是拖后腿的,是不是觉得很怪异?项目采用框架的目的是为了在工程角度上,更高效、更便捷、更高性能地对项目进行开发和维护。之所以需要框架是因为相对于服务器开发而言,本地程序的开发考虑事情比较少,比如不太需要顾虑性能、不需要考虑大并发等。框架帮我们做了很多这方面工作,以帮助我们解决线上项目的需求。但是在Serverless中,对于普通项目来说,框架已经失去了大部分的价值和意义。
- 性能弱化:在Serverless中,其实我们使用的不是服务器而是计算能力,鉴于云函数本身提供的计算能力相当强,因此即便是质量差的代码,也扛得住,框架的高性能其实已经被弱化。
- 并发弱化:对中小项目来说,绝大部分的业务执行时间是很短的,高并发的压力并非来源于高效算法压力,而是来源于流量和计算资源的瞬间增长超过了服务器提供的能力。云函数每次调用可以说是物理隔离的,因此云函数其实就相当于是“自动无限膨胀”的计算和网络资源,因此不惧高并发。框架的高并发方面优化的需求其实也就可有可无了。
- 功能失效:在Serverless中,传统连接池失效,我们需要独创连接池,各大云服务商的数据库也为云函数的大量链接需求进行了优化,直接提供2000以上的同时链接支持。
- 学习成本:中小项目不需要高深技术,没有庞大的业务链,快速简单才是需求。任何框架,再简单的框架都需要学习成本,大多数技术开发者也仅仅只是百度下用法就开始使用,并不会深入研究。因此越是小的项目,当框架本身不满足或者出现问题的时候,框架本身就成了最大的障碍。对于中小项目,也有人为用框架而用框架。
- 框架不支持:如上所述,大部分语言的框架“事件函数”并不支持。
- 没有Serverless的原生框架。
Serverless技术框架说明:
要想充分发挥Serverless的优势则必须采用多函数部署,即微服务架构模式。Serverless最终、最好的归宿一定是微服务架构模式,现在的各传统框架只是没有原生框架前的临时过渡。
传统微服务框架一般是针对大项目,有着很高的学习和入手成本。中小项目的微服务其实异常简单,我们并不真的采用微服务框架,而是像写本地hello world一样开发项目,部署时一个API接口一个云函数。
我们要微服务的好处,不要他的麻烦。因此我们应该采用的模式是:传统架构+传统开发+微服务式部署。
最简单的方式就是采用简单的框架,然后将每个和客户端交互的API部署成单独的函数。一个高效的Serverless开发框架,必须要支持本地单元测试,并且单元测试的效果必须等同于部署后的执行效果。因为不方便测试的框架会让开发者偷懒,等待功能部署后再测试,这容易造成很大的返工问题。单元测试的实现逻辑可以参考我上个文章。
因此在我看来,对于中小项目来说,当不用框架不影响团队协作和效率的时候,就不需要上框架了(传统框架对云函数并不太匹配),或者自己写个简单的共性项目结构或框架即可。以API接口为单位进行部署,部署完毕后直接就形成了微服务。
开发时只需要特别注意全项目不存在session,各个API接口执行时是互相物理隔离,数据不互通的。
我的项目采用的框架是针对Serverless的自研框架,已经使用了多个项目。该框架较好的利用了云函数的各项特性的同时,不但没有增加开发难度,反而降低了,低到我都感觉有点LOW。如图:
- xxxxapi.php:此为接口文件,位于项目根目录下,是依据功能拆分的全部云函数的执行入口,比如adminapi.php下的sendadminsms函数,部署的时候云函数名叫做sendadminsms,API网关为:/admin/sendadminsms。注意事项:多个接口文件中函数名不可以重复,因为云上的云函数的名字不能重名。
- ctrl目录:类似其他项目的control模块,负责业务代码。比如: AdminCtrl.php。
- model目录:数据库模块,负责数据库操作,如: AdminModel.php。
- vendor中的simplescf:核心库我自行研发了一套专门针对腾讯云函数的核心库,实现了云函数动态调用、动态控制、单元测试的执行、数据库的封装、日志的处理和一个极便捷的ORM数据库封装(支持TCB免费数据库)等,类似微信云云开发的SCF版本。微信云的云开发限制性很大,本框架可以同时支持WEB、小程序、APP。
- 整体调用顺序: 部署完毕后,客户端-->API网关-->xxxapi.php入口函数--->ctrl处理业务逻辑-->model处理数据。
第四步:项目分工进度安排
Serverless的项目管理中,任务的分工不能简单的按照传统的功能模块来分工,而是以API为单位指定责任人,并进行工作量评估,测试也以API为单位。
若项目涉及协作,完整的流程建议:
PM预先创建好各API,并制定好入参和出参。轻度的创建是预先定义好调用入口函数;深度的创建不但创建入口函数,同时将DEMO代码部署到云上,深度创建可以有效的让前后台异步开发。
对API接口安排负责人,并制定开发计划。
尽量每人负责的API任务是共性的,比如此人负责的基本是raceapi.php接口文件中的函数。
将项目的公共功能提炼成公共模块。
建立好单元测试,让本地化测试(单元测试TDD)高保真模拟云执行是高效非常重要的点。
第五步:项目部署
当前Serverless的部署基本就是三种:管理后台、Serverless Framework CLI和SDK。
- 管理后台:你得打开网页,你得给成员账号密码,你得登陆,可能多个人都同时需要,就是两个字“麻烦”。
- Serverless Framework CLI:需要yaml配置文件,需要你自己修改配置,配置错了可能把你的项目就冲了,需要你给key,要不搞那种什么二维码扫码,这真的是中国特色,很是想吐槽。我一个重度使用者偶尔也会配错,还会把已有配置给冲了,为此我差点砸了桌子。
- SDK:别想啦,你为了部署会自己研究SDK吗?一个触发器可能需要2个产品的SDK配合才可以。因为我是腾讯云云函数的devops开发者,所以我是SDK重度使用者,但是我不认为一个单独的项目开发人员会搞这东西!浪费的时间还不够雇个人专门给你部署呢!
项目中使用微服务模式部署,可能会有上百个API ,也就是上百个云函数,最多的时候我一个项目部署了近300个云函数,如果CLI来部署,是不是得折腾300个yaml,如果中间要更新某个函数代码,我还得配置更新代码的 yaml,如果要同时更新多个函数代码呢?这三百个你还不能出错,这么一想,CLI对我们小项目还是很尴尬的。
那么CLI的优势是什么呢?他可以跟CI进行完美整合,通过CI来实现项目的自动部署,因此大型项目用这个用的很嗨,但是小项目来说,单元测试都不写,你还跟我说CI?
所以整体下来,是不是感觉中小项目在部署这个工作上会碰到很大的问题。我的解决方案是自己搞了一个GUI部署工具,一键更新(秒级部署、更新函数代码),还隐式做了项目管理工作的引导功能。差不多2个月后,工具会开源给大家免费用。
作者:Sheldor,知乎账号:小助君,欢迎关注,了解更多关于Serverless的实践经验。