本文做者:IMWeb IMWeb团队原文出处:IMWeb社区 未经赞成,禁止转载html
导语:Serverless云函数的优势是不怕高并发,理论上无限自动扩容,缺点是冷启动特性致使冷启动的时延比较高。那么实际上性能如何,而且是否还有性能优化的空间和手段呢?node
最近试点Serverless的一个项目是从原有的node服务迁移到腾讯云函数Serverless的。既然是项目迁移,那么就要对比一下迁移先后的性能了。python
从测试同事那很快就找到压测大师这个工具,压测大师配置和报告都还算比较完善,是腾讯出的,内部的话用企业微信登陆直接免费可使用。web
缺点是:发请求的时间间隔有限制,最大只能隔1分钟,那就没法纯测试云函数的冷启动了,不过每一个阶段都有自动增长人数,页能间接测试到冷启动到性能,看到测试结果时不时飙升到高耗时,那就多数就是冷启动的耗时冷。chrome
压测大师连接:wetest.qq.com数据库
若是要测200之内的并发人数的话,能够直接测试了。若是须要测高于200人数的并发量的话,须要先进行域名验证(具体能够看压测大师提示并操做便可),就是放一个key到你的域名根目录下,可让压测大师能够访问到,否则让你随便压别人的域名怎么办?后端
这又难倒了我。由于腾讯云自动生成的api网关连接下必然会有http://yourdomain/release/这个环境的路径,根本没法将key放到根目录下。api
腾讯云也提供了一个路径映射的功能,能够将这个/release/的路径去掉,可是这个功能绑定在了自定义域名中,就是说,首先你得有一个本身的域名。跨域
这个问题和腾讯云的产品反馈以后,将这个需求加到了排期中。浏览器
暂时我从同事那借用了一个子域名先进行继续将测试工做进行下去。
注意:须要在腾讯云备案了的域名。能够绑定一个子域名,在我的的域名管理界面中,经过cname指向腾讯云的API网关域名便可。
若是你要支持https的话,还须要申请个证书。有免费的能够申请,同一个主域名能够申请20个。申请完成以后,将证书上传到腾讯云便可。
若是不须要https都话,直接选http就能够了,准备工做都OK了。
选择测试的CGI,初步是要比较二者的链路,因此选取一个简单的逻辑,只有一个数据库查询的CGI。
压力从低到高进行尝试。
刚尝试到200并发人数到时候,成功率就有点不对劲了,只有80%多?
后来查了一下云函数的日志,问题就比较明了了。
虽说是理论上能够无限扩容,可是也要配置给不给你这个上限。
若是有需求能够联系腾讯云的同事进行相关资源的申请。
在提升限额和初始化一个资源池待用以后,再来压测一下:
从上图能够看到成功率上去了,可是平均耗时和耗时长的部分仍是很多。
将耗时比较长的拿出来和云函数的开发一块儿分析一下,耗时耗在哪里了。
一、 有资源池,冷启动的状况下:
1)资源申请:代码比较大,代码解压+load代码 约2.5s+(解压2.4s),若是加上下载估计会在3s多。
若是调用很频繁,正常状况会有二、3百个请求(资源池容器数量)资源申请时间在2.5-3s之间; 若是调用不频繁,耗时2.5s-3s的请求数会更多一些。
2)函数调用:代码自己执行时间:70ms~115ms左右,路径耗时从5ms~600ms不等
复制代码
二、热启动:也就是代码自己执行的时间,这个看代码自己要作的逻辑。机器不是瓶颈,主要是逻辑和须要调用第三方应用的耗时。我这个压测例子的耗时就会在50ms以内,20ms左右。
三、如今有一些大于5s的,那些耗时都在路径上或者有可能在单节点处理能力上。具体消耗在哪里暂时看不出来。
一、设置实例保留,减小冷启动。这个最有效,降幅最大,至关因而保留了一个进程随时响应请求。
二、设置合适的资源池数量,能够大大下降冷启动的耗时。
三、减小代码量,我这个例子代码量从58M下降了26M,主要是将并不经常使用并且代码量比较大的库拆分红一个单独的云函数服务。
理论上结果应该会好看不少了?
实际上耗时最大的请求的确有所改善,可是平均值和90%的值仍是被一些高耗时拉高。
可是实际上压测大师测的结果依然没有达到很理想,下面汇总一下截止目前阶段的结果。
理论上云函数服务该作的优化都作了,并且理论表现不会这么差才对?
后来云的同事用python写了脚原本本身压测,发现200并发的平均耗时在200ms以内,并且超过200ms的请求也在可数以内。
因为两个测试的结果不一致,从本身写的脚本和wetest压测方案两方展开分析。
1)脚本尽可能去还原wetest的方案,如异地部署,阶梯增长并发,而且每一个阶段维持30s。
2)直接找到了wetest的后台同事进行问题沟通,尝试了长链接,短链接,多IP压力源,去掉日志打印等操做。
结果:这个压测结果其实已经达到了咱们预设的优化目标,平均在200ms以内。
如下仍是wetest的压测结果(短链接+多IP)。
其中还有一个颇有意思的结果,长链接下的压测结果:
那么究竟是什么缘由致使了这个结果的差别呢?
“网络链接耗时”
在这个例子中,将长链接改为短链接,从一地压测改为多IP压测,效果最为明显,去掉日志打印也必定程度减小了压测源的性能损耗。
既然地域不一样,网络不一样,耗时差别这么大,那么真实的用户耗时到底如何呢?
红色的是Serverless,黄色的是原来的NodeServer。
刚开始是由于设置了header头,浏览器认为这个是非简单请求。
非简单请求的CORS请求,会在正式通讯以前,增长一次HTTP查询请求,称为"预检"请求(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可使用哪些HTTP动词和头信息字段。只有获得确定答复,浏览器才会发出正式的XMLHttpRequest请求,不然就报错。更详细能够查阅:跨域资源共享 CORS 详解
图为一个请求产生了两个请求,第一个是预检请求,其中method为OPTION, 返回状态码是204。
若是要用到非简单请求的时候,服务端响应CORS的设置要注意到:
若是单选具体的GET,POST,能够在API网关中的API管理中设置是否支持CORS,若是须要支持多个的请求方法的话,就只能后端业务处理。
继续分析发现:Serverless的请求会比NodeServer请求多一个Initial connection和SSL的时间。
为何NodeServer没有呢,由于咱们测试的页面和发请求的页面是同域的,因此这部分时间省了。为何以前Serverless没有发现呢,由于socket链接以后没有那么快销毁,在页面重复刷新的时候,反而是看不到这个耗时的。
须要清理一下socket: chrome://net-internals/#sockets
就能够复现了,那么这个耗时差距的缘由就很明显了。
我作了一个简单页面进行测试,发现这样的结果。Serverless和NodeServer的全程耗时其实差不太多,可是TCP链接和SSL时间会长不少。
这是为何呢?我测试的这个Serverless是部署在上海的,而我在深圳进行测试的。
我再作了一个测试,加了一个部署在广州的云函数。
结果也很明显了。
异地访问部署的问题,由于原有的NodeServer接入了STGW。
STGW全称Secure Tencent Gateway,腾讯安全云网关,是一套实现多网统一接入,支持自动负载均衡的系统。因为STGW提供了就近接入和SSL加速,因此这两部分时间都相应有很多的优化。
那么Serverless能不能用多地部署,就近接入来解决这个问题呢。
目前Serverless的云函数和API网关都是地域隔离的。也就是说广州的API网关对应广州的云函数,不能一个网关对多个地域的云函数。这个需求和腾讯云的产品沟通以后,归入到之后的规划建设当中。
那么咱们目前有没有折中的方案呢?
咱们设想了一些中转的方案:
最后咱们选择了最右侧的方案,主要是简单。
并且还能够继续经过在header中设置preconnect减小TCP握手和SSL的时间。
<link rel="preconnect" href="//example.com">
preconnect的兼容性状况:
使用以前:
使用了以后的效果:
能够看到Initial connection 和 SSL的时间是能够直接节省掉了,在网络差的状况下,这部分节省的时间更为显著。
Serverless云函数性能评测和优化结果:
通过优化以后,Serverless云函数的响应性能已经达到了须要即时返回场景的可用状态。
在API网关监控到到耗时(不包括网络时间和握手时间)
一、压测方案、问题分析
1)wetest是腾讯公司支持的通用压测方案,要用好也要对里面提供的设置了解清楚用法和用途。
2)测试不限于压测工具,本地脚本,浏览器network分析,线上用户test,等等均可以尝试用来评测分析。
复制代码
二、性能优化方案
云方面的优化:
1)上限设置
2)专用资源池
3)实例保持
4)架构升级(测试中)
5)就近接入(待规划)
复制代码
代码方面的优化:
1)代码逻辑和第三方调用
2)拆分不经常使用功能,减小代码量
3)使用预加载减小connect的时间(preconnect)
4)接入STGW进行转发
复制代码
咱们深刻一点从云函数的启动过程来分析一下耗时在哪里,如何去针对这些具体的步骤进行优化。
函数发生调用,调度系统看函数实例是否存在,若是实例存在,那么就能够执行函数,返回结果。这个时间是很是短的,在毫秒级别。
若是不存在,那么须要建立容器,下载部署代码。这些过程耗时百毫秒到几秒不等,称为冷启动。
优化函数的性能,也就须要从函数生命周期的各个阶段去优化。
这些都是平台作的优化,那么开发者能够作什么呢?
一、云函数目前还在起步阶段,应用的过程当中还会遇到这样那样的问题,好在腾讯云的同事们(@masonlu等)积极响应,主动和咱们一块儿寻找问题解决问题,最终一块儿共同成长。
二、云函数目前的特色就是不适合对时延要求比较高的应用,不适合有状态的应用,可是这个不是必然的,这两个问题有来合适的方案以后,就不会再是问题。