忽如一晚上春风来,千树万树梨花开
,云原生的浪潮伴随着云计算的迅速发展仿佛一晚上之间,迅速侵袭了技术的每一个角落。每一个人都在谈论云原生,谈论云原生对现有技术的变革。
Kubernetes已经成为容器编排的事实标准,Servicemesh正在被各大厂商争先恐后的落地实践,Serverless从一个一直以来虚无缥缈的概念,到现在,也被摆在台面,有隐隐约约崛起的势头。
只是没想到,在后端闷头搞容器化、上Kubernetes、尝试Servicemesh的时候,Serverless却先在前端火了起来。从今年的GMTC全球前端技术大会上,Serverless主题的火爆就可见一斑。笔者也看过一些网上流行的讲Serverless的文章,观点大同小异,实践几乎没有,误解与谬论满篇飞。本文倒无心挑起争论,只是试图从一个云计算研发的视角出发,聊一聊咱们眼中的Serverless。前端
前端为何想要上Serverless,其实也很好理解,node.js的普及、前端工程化以及BFF的兴起,愈来愈多的前端须要关心服务的构建、部署、运维,服务的日志、监控报警等等,严重拖累了前端的开发效率,让前端花不少时间在服务器上排查问题,无疑是痛苦而低效的。
对于前端来讲,最原始的诉求是,我不肯意管服务器等底层资源,哪台节点宕机了,麻烦不用通知我;流量太大了,服务须要扩容了,我也不想关心;我只须要写好代码,就能够自动部署到服务器上,代码有bug,能让我看日志和监控排查问题就行。
其实这也不仅仅是前端的梦想,不少后端或者数据类的研发,也有一样的需求。不过咋看很美好,可是仔细想一想,有一些后端的业务很复杂,服务间调用关系以及各类特异化需求其实很难适用于Serverless,想彻底不关心底层的服务器,有点困难。
因此,Serverless并不是银弹,关键是看业务场景和需求,就算只有50%的业务适合,能解决这50%业务的问题,那也是了不得的成就。node
了解Serverless的同窗,或多或少都听过Faas,Faas即Function as a service,通常都称为函数计算。
做为开发人员,只须要写一个函数,就能够在例如AWS Lambda等各类函数计算平台上运行起来,真正实现了对服务器的无感知,同时能够对外快速暴露API接口,能够基于函数级别的自动扩缩容,能够监听各类事件进行触发。
并且Faas结合云平台的webIDE,若是webIDE设计的足够好,能够给咱们带来云平台上更方便的开发体验,结合云上的各类工具和生态,将来会有更大的想象空间。
不过,显而易见,以函数为最小粒度,有一些局限性。
微服务是以功能职责为划分,拆分红一个一个专一于特定功能和需求的服务,为了解决微服务之间的网络调用和流量管理,引入了不少服务治理等相关的功能和组件,能够想象一下,若是把服务模块再拆分为函数的粒度,函数之间的调用关系无疑会爆炸,再思考一下,如何把老的服务改形成Faas形态,如何复用函数之间的逻辑,如何管理大量函数代码,这无疑对开发者带来了不少困扰。
因此,Faas不太适合通常后台长期运行的web服务型应用,真正适合的是那些数据计算、批处理等业务,这些业务逻辑比较单一,运行完能够中止,并且更适合Serverless中基于事件触发的特性,冷启动的延时也无所谓。
Faas的一个基本特征是无状态,那实际上的数据或者状态该如何存储呢,因此说到Faas通常都会说起Baas,即Backend as a service,不过相似的Xaas的名词太多了,Baas这个名词看着就像是有人为了强行补充Faas没有干的活儿而起的。所以有些人粗暴的总结Serverless = Faas + Baas,固然若是你要强行认为Serverless就是函数计算,那这个也没有问题。
不过,咱们的观点是:Faas只是Serverless的一种特例。在这个世界上,除了Faas,还有更多的无状态工做负载适合以Serverless的形态去运行。git
除了服务的粒度不同以外,无状态工做负载和Faas通常都具备如下Serverless的特性:github
既然是Serverless,开发者真正关心和面对的是代码层面,因此无论是函数仍是一个代码工程,一键构建和部署是咱们的终极指望。
Kubernetes生态下有各类CI/CD解决方案,可是缺少更加一键式的工具能够帮咱们将代码(函数)迅速转变成部署的服务。因此,一个足够好用的本地client工具、一个完善而高效的CI/CD平台很重要。对于Faas,可让用户便捷的将函数部署到Serverless平台,对于无状态负载,则能够根据用户需求暴露一些构建的自定义配置和流程。web
在Kubernetes上通常服务实际的运行都或多或少的须要咱们建立不少的Kubernetes资源,例如service、ingress等,而Serverless会作更多的自动化操做,以便更方便的提供服务。例如,Serverless平台会自动提供流量入口和路由,部署完成后能够迅速对外提供服务,同时提供相似蓝绿发布、灰度等流量管理等功能。算法
毫无疑问,Kubernetes也有HPA能够提供自动扩缩容。不过,HPA敢让服务副本数缩为0吗?固然不敢,试想一下,若是服务的副本数为0,至关于再也不运行了,用户的流量如何导入呢,用户连服务的接口都调不通了,HPA更没有metric数据来感知去扩容服务了。HPA没法缩容为0,对于某些短运行的计算类服务来讲,是没法接受的,由于这样就不能真正的作到无服务,不实际运行时不占资源不计费。
固然Serverless能够作到,让服务在没有请求时自动缩为0,在有流量的时候从0启动,或者流量增大时快速的扩容,迅速应对流量的变化。
不过,还有一个Serverless业界都很关注的点,就是服务从0扩容为多副本时启动的延时时间,通常称为冷启动的问题。若是冷启动时间太长,对于用户的第一次请求确定有很大影响,业内也有不少大厂在作一些优化。可是若是不是直接面向用户流量的服务,例如我只想跑个数据处理算法,其实也不在意这几百毫秒的启动延迟,若是是相似前端的web服务,恐怕大部分人仍是宁愿空跑一个单副本的服务,也不肯意冒这个风险吧。小程序
Serverless的另一个特征是基于eventing事件进行触发,事件其实是一个比较抽象的说法,不少东西均可以理解为事件。例如,用户的请求能够认为是一个事件,git的webhook能够认为是事件,kafka上有了消息能够理解为一个事件,包括Kubernetes的各类资源操做等等都是。因此,其实事件触发咱们并不陌生,咱们的平时开发和设计架构里常常都会有意无心的使用到事件触发的机制,只是太过日常,反而没有人去注意和抽象出这么一个理念。
如今你们都在倡导云原生,不少服务都是往云上迁移和部署,事件触发机制在云上能够有更多的扩展性和想象力。例如,咱们的Serverless应用能够监听云上的中间件或者基础组件的事件,经过这些事件,触发特定的Serverless应用,从而打通云上的Paas服务,实现云上服务的一体化。 后端
总结下来,虽然目前Serverless很火但咱们更应该静下心来思考,为何会有Serverless的诞生,Serverless最原始的需求和驱动力在哪?是Kubernetes不够好用仍是Servicemesh不够友好?
Kubernetes被认为是下一代的分布式操做系统,操做系统上必然会运行各类各样千奇百怪的程序,有的须要直面系统内核,有的只是提供用户更好的UI,不过,有一类程序能够以更便捷的方式去编译、运行,而提供这一切的工具与平台就是Serverless。
因此,Serverless其实只是一种云原生应用更为特殊的实现和表现方式,也有不少的应用并不适合以Serverless的方式去运行。无服务器当然是愿景,大量的封装和抽象让开发者无需感知不少东西,但这个宇宙运行的规律可能并不是直白的线性系统,混沌和复杂性才是常态。若是有人告诉你,Serverless是全部应用的终极目标,那只能引用一句长者的话,too young, too simple
。前端工程化
基于Serverless的特性,咱们也能够推导出比较适合Serverless的应用都有哪些:缓存
其实还有不少,不过须要指出的是,这些都能在咱们常规的容器云平台上构建部署运行,只不过,有了Serverless更高层次的抽象和封装,咱们能够更快的开发构建部署,服务能够有更好的运行姿态,从而一步步接近咱们想象中的那个只用写代码,不关心服务器的美好愿景。
做为Faas鼻祖的AWS Lambda其实早就已经推出了,但最近的几年内其余云厂商才慢慢跟上推出函数计算服务。 相信国内的不少公司也在尝试Faas或者Serverless架构,不过能够猜想出你们或多或少都心存疑虑或者有不放心之感,不敢真正的放上本身的线上服务。
目前看来,虽然Serverless市面上都吹的很火,但实际落地的寥寥可数,星星点点的一些火花,仍是难以造成燎原之势。Serverless这片土地十分辽阔,可是各大云厂商却都是在本身和本身过家家,至于其余人怎么玩的,就不怎么关心了。
因此,目前一个很大的问题就是咱们在一家函数计算平台跑了本身的服务以后,基本上就和这个平台绑定了,特别是若是你还用到Eventing,因为都是基于平台内部特定的事件触发机制,迁移成本仍是比较高的。
终极缘由,目前尚未一个强势而大一统的框架和平台,可让你们甘愿臣服。想当年,容器编排领域兴起,Kubernetes和Mesos大战,两边各自有人站队,云厂商也各自押宝,现在Kubernetes一统江湖,你们都默默的创建起了基于Kubernetes的容器云平台,因而围绕着Kubernetes的云原生生态蓬勃发展。
因为没有统一的平台,针对Serverless目前还存在的一些局限,你们作的优化和改进也是各自为战,难以落地生根。
虽然现在已然是2019年了,但咱们仍是看到了一些但愿和将来的苗头。CNCF云原生计算基金会的Landscape中专门对Serverless分出一页(https://landscape.cncf.io/format=Serverless
),上面总结了Serverless相关的各类平台和框架,其中目前最为火热和最有前景的即是Knative了。Google Cloud已经基于Knative推出了Cloud Run,阿里云的Kubernetes容器服务也最近引入了Knative的内测,这让咱们无疑看到了将来统一Serverless平台的但愿。
Knative是谷歌开源的Serverless架构方案,旨在提供一套简单易用的Serverless平台,把Serverless 标准化。Knative不局限于Faas,而是指望可以运行全部的无状态工做负载。像其余绝大部分的Faas或者Serverless平台同样,Knative也是基于Kubernetes,不过,Knative还基于Istio或者Gloo网关等实现流量的分发和管理。
还在不久以前,Knative分为三个组件:
Build负责将代码转换成咱们须要的容器镜像,Serving则是提供Serverless的运行方式,Eventing则致力于提供标准化的事件触发机制。
不过,如今Build模块已经被弃用,被由Build的设计思路而发起的Tekton项目替换(参考:《Kubernetes原生CI/CD工具:Tekton探秘与上手实践》)。固然你也可使用其余合适的CI/CD工具替代。
Serving模块主要作的工做本质上就两个:
以基于istio为例,Knative自动建立istio的ingressgateway,服务的service等,将流量导入新部署的服务,而不须要手动的建立各类service,ingress暴露服务和流量入口。同时,将不一样版本对应不一样的deployment,能够方便的实现蓝绿、灰度等发布部署方式。以下图所示:
Knative有自身基于流量请求算法的metric自动扩缩容(KPA)的方式,也支持Kubernetes原生的HPA实现自动扩缩容。同时,在服务缩容为0以后,Serving会将服务流量路由到冷启动的组件,缓存请求,而后扩容服务,再将流量导入启动后的服务副本。
Knative Eventing则联合 CNCF Serverless WG制定一套事件格式规范并推广(https://github.com/cloudevents/spec/blob/master/spec.md#design-goals
),只须要各个云厂商都按照这个规范,咱们的Serverless服务就能够进行跨平台的事件触发,也不会被特定的云厂商绑定。 固然,Knative的具体使用和实现细节很难用简单的几句话解释清楚,若是有兴趣,欢迎关注咱们后续对Knative深度剖析的系列文章。