如果现在别人问你知道什么是Serverless吗?你回答说不知道,那一定会被别人说你不够潮,都1202年了,还不知道Serverless。好吧,如果你真的不知道什么是Serverless也没有关系,这篇文章我不是来科普Serverless的,要学Serverless的自行去Google学习一把。

这篇文章我主要想谈一谈Serverless现阶段存在的一些问题,以及我为什么不推荐现阶段在生产环境中使用Serverless架构的原因

如果面试有人问你什么是Serverless,这样回答就可以了:Serverless是一种架构模式,中文翻译过来是无服务器的意思,但并不是说真的不存在服务器了,只是不需要购买、管理服务器,只需要关注代码逻辑,执行结果。它最大的优势就是按需付费,毫秒级计费,以及无限扩容。

嗯,这样的回答基本上就没错了。但是,事实真的是这样吗?

我不推荐现阶段在生产环境使用Serverless架构的原因

开发者的学习负担

虽然Serverless的理念很好,让我们只关心代码的编写,只需要编写一个个函数就可以了,但其实你想将Serverless用在生产环境,有一大堆的概念等着你学习,以腾讯云云函数为例,你需要掌握了解:什么是触发器?什么是别名?什么是冷启动?什么是Web函数?什么是层?什么是容器镜像?怎么部署一个Serverless应用?等等

当你学完这些概念,算是对Serverless云函数有一个开发级别的大概了解了,你觉得这个成本高吗?真的像宣传一样只用关注代码逻辑吗?当你使用一项新技术的时候,如果它带来的收益不能远远Cover住你的成本时,我觉得这是不划算的,投入产出比很低。没关系,你说我花了时间学了新技术,还用Serverless按量付费省钱,以及无限扩容提高性能啊。

那好,接下来我就一条一条说。

传统的Serverless函数接入HTTP需要一层适配器转换

Serverless函数是由触发器触发的,你在函数内部接收到的只有一个事件(Event),这意味着,你想在函数内获取请求路径、参数都需要额外的转换,当然,这难不倒我们程序员,我们在本地还是通过HTTP访问开发,当函数需要上传到云端时,通过打包构建流程,自动在代码中加入一段适配器Proxy,帮我们做 事件-> HTTP 的转换。看起来很美好,但这无疑加重了我们的心智负担,还隐隐的埋了一个坑,当程序出现Bug时,你想调试代码,一堆很乱的堆栈会让你排查Bug无从下手。现在有一些云厂商明白了这个道理,在平台层面帮我们做了这个适配。下图是腾讯云的做法:

image.png

这样,你在本地开发和远程云端的代码就是一致的。当然,多一层抽象就意味着性能会差一点。

开发工具问题 每次上传代码要10多秒

我们每次开发完一个函数,想在云端集成测试一下,需要将函数打包上传到云厂商平台上面测试一下,这时候,烦恼来了,将代码以及依赖库全部打包成压缩包,这个体积就很大,更别说我们Node.js的npm hole,随便打包一下,代码包就超过了100MB。

image.png

上传速度可想而知,当你频繁调试代码频繁上传代码时,这感觉,贼爽,可以光明正大的喝咖啡了。

可能你会说你可以用部署啊!

层是万能的吗?

用层,相当于我们把代码和依赖抽成两部分上传,把不频繁改动的大体积依赖抽离出来,需要改动的函数逻辑则相对体积小上传速度会快很多,这在我看来都是曲线救国,我们应该在上传前就判断出哪些文件有改动,只更新有改动的这些代码,当然,这个技术可能难度比较高,这也是为什么云厂商没有推出这个功能的原因。另外,多出一个的概念,意味着你要随时关注层的更新,可能哪里你本地的依赖库更新了,但层忘记更新了,这时,找Bug的痛苦会让你永生难忘。多出的概念意味着你的心智模型要考虑的事情更多了。

冷启动问题

当你的函数首次运行时,云厂商需要初始化平台配置,配置弹性网络,拉取镜像,拉取用户代码,初始化运行时,执行函数。 总共的耗时没有你想像得那么快,极端情况可能达到10秒。

image.png

如果用户访问的是一个接口,会不会觉得你的系统挂了。如何避免函数的冷启动是一门学问,要对函数资源,以及云厂商的特性了解十分到位,比如腾讯云的解决方法是预置并发,阿里云是预留实例,所以,当你用了一些优化方案后,你可能就被某一云提供商绑定死了。而且,这些方案都是有成本的,成本就是你要用预留实例,你的费用就上来了。

函数费用问题

我们知道,使用虚拟机的费用是确定的,而函数嘛,是按量付费的,意味着你只能估算出一个月大概多少费用,函数的收费的公式是:

费用 = 函数内存配置大小*运行时间 

的确是按次收费,但根据实际测试,当你的虚拟机利用率达到一定程度时,费用就比使用函数少了,随你的虚拟机利用率的提升,这个差额会越来越大,所以,想办法提升你虚拟机的利用率吧,用不了那么高的配置就降低一点,这成本不就降下来了吗。

其实函数费用这里还有一点特别要说的就是,想把函数费用降下来,你需要对你的函数划分的颗粒度有很好的规划,比如你有10个函数,其中只有一个函数需要用到大内存,那如果你将10个函数一起打包上传,那收费就是按这个最大内存来收取的了,拆成10个函数也不好,颗粒度太细,不利用维护。理想的方式是拆成两个函数,即使用相近内存的函数拆分在一起。但,这无疑又加重了我们的心智负担。

性能问题

理论上是无限弹性扩容,但实际上各云厂商都有自己的并发上限,也就是说并不是无限扩容。

以腾讯云为例:

在地域维度,每个账号的弹性并发的扩容速度默认限制为500个/分钟,即在1分钟内,最多可以启动500个新的并发实例。

不仅支持的请求是有上限的,包括函数的个数,触发器的个数等等都是有上限的。当然,这样也是有好处的,当你被攻击时,函数的费用不致于让你直接破产。有时间可以用你的应用测算一下,支持同等并发的虚拟机的费用是多少。

你以为的Serverless只是计算 其实我们需要的是一系列的生产可用工具

把函数上传到云平台就万事大吉了吗?这可不是大学做项目,应用挂了重启下就解决了,反正没什么用户。真正的商业应用,宕机一分钟,那损失的可是真金白银和我们的口碑啊,所以一定要保证生产就绪,我们需要好用的开发工具,测试,在线调试,跑性能,看日志,查监控,调用链,限流,熔断等一系统生态,而这些功能,云平台只提供一个非常简陋的解决方案,单这里面的任何一个节点,都可以拿出来做一个超大项目了。所以云函数想走得更远,怎么提供这一系列的生产可用工具是个大问题。

image.png

其它一些小问题

Serverless 依赖安装要和线上环境一样,当你需要安装一些和系统相关的依赖时,你需要和云平台保持一致,这无疑又是一大难题,虽然云平台内置了一些主流依赖,但版本比较旧。如果你使用自定义镜像部署,那你最好把你的镜像大小优化好,不然镜像上传时间够你喝一壶了。

对Java,PHP这类重运行时的语言支持不好,如下腾讯云描述:

Java 语言由于需要编译后才可以在 JVM 虚拟机中运行。因此在 SCF 中的使用方式,和 Python、Node.js 这类脚本型语言不同,有如下限制:

  • 不支持上传代码:使用 Java 语言,仅支持上传已经开发完成,编译打包后的 zip/jar 包。SCF 环境不提供 Java 的编译能力。
  • 不支持在线编辑:不能上传代码,所以不支持在线编辑代码。Java 运行时的函数,在代码页面仅能看到再次通过页面上传或 COS 提交代码的方法。

Node.js,Python是云函数的重点语言,但这两个语言都有自己的局限性,很大程度也限制了云函数的边界。

BasS层,Serverless数据库靠谱吗?不靠谱,现阶段很不靠谱,我自己试用了一下,数据库也按量付费是非常好的理念,但如果遇到冷启动,数据库启动时间可以长达1分钟,这我实在没法接受。

你会用Serverless吗

说了这么多,你会用Serverless吗?

我觉得现阶段去了解它,学习它,拓宽自己的知识面,是非常不错的,但是用到生产环境,我是不推荐的。

玩玩可以,千万别认真。

我承认我是有在用Serverless的,但仅限于一些简单的应用,现阶段Serverless在一些旁路需求还是很有价值的,比如视频转码,直播录制,文件处理,跑跑离线数据,搭搭个人博客。如果你有这方面的需求,用Serverless是可以节约很多成本的。

期待Serverless生产可用的一天早日到来。

Serverless Go Go Go.

image.png