精读《Serverless 给前端带来了什么》

引言Serverless 是一种 “无服务器架构”,让用户无需关心程序运行环境、资源及数量,只要将精力 Focus 到业务逻辑上的技术。现在公司已经实现 DevOps 化,正在向 Serverless 迈进,而为什么前端要关注 Serverless?对业务前端同学:会改变前后端接口定义规范。一定会改变前后端联调方式,让前端参与服务器逻辑开发,甚至 Node Java 混部。大大降低 Nodejs 服务器维护门槛,只要会写 JS 代码就可以维护 Node 服务,而无需学习 DevOps 相关知识。对一个自由开发者:未来服务器部署更弹性,更省钱。部署速度更快,更不易出错。前端框架总是带入后端思维,而 Serverless 则是把前端思维带入了后端运维。前端开发者其实是最早享受到 “Serverless” 好处的群体。他们不需要拥有自己的服务,甚至不需要自己的浏览器,就可以让自己的 JS 代码均匀、负载均衡的运行在每一个用户的电脑中。而每个用户的浏览器,就像现在最时髦,最成熟的 Serverless 集群,从远程加载 JS 代码开始冷启动,甚至在冷启动上也是卓越领先的:利用 JIT 加速让代码实现毫秒级别的冷启动。不仅如此,浏览器还是实现了 BAAS 服务的完美环境,我们可以调用任何函数获取用户的 Cookie、环境信息、本地数据库服务,而无需关心用户用的是什么电脑,连接了怎样的网络,甚至硬盘的大小。这就是 Serverless 理念。通过 FAAS(函数及服务)与 BAAS(后台及服务)企图在服务端制造前端开发者习以为常的开发环境,所以前端开发者应该更能理解 Serverless 带来的好处。2. 精读FAAS(函数即服务) + BAAS(后台即服务) 可以称为一个完整的 Serverless 的实现,除此之外,还有 PASS(平台即服务)的概念。而通常平台环境都通过容器技术实现,最终都为了达到 NoOps(无人运维),或者至少 DevOps(开发&运维)。简单介绍一下这几个名词,防止大家被绕晕:FAAS - Function as a service函数即服务,每一个函数都是一个服务,函数可以由任何语言编写,除此之外不需要关心任何运维细节,比如:计算资源、弹性扩容,而且可以按量计费,且支持事件驱动。业界大云厂商都支持 FAAS,各自都有一套工作台、或者可视化工作流来管理这些函数。BAAS - Backend as a service后端及服务,就是集成了许多中间件技术,可以无视环境调用服务,比如数据即服务(数据库服务),缓存服务等。虽然下面还有很多 XASS,但组成 Serverless 概念的只有 FAAS + BAAS。PAAS - Platform as a service平台即服务,用户只要上传源代码就可以自动持续集成并享受高可用服务,如果速度足够快,可以认为是类似 Serverless。但随着以 Docker 为代表的容器技术兴起,以容器为粒度的 PASS 部署逐渐成为主流,是最常用的应用部署方式。比如中间件、数据库、操作系统等。DAAS - Data as a service数据即服务,将数据采集、治理、聚合、服务打包起来提供出去。DASS 服务可以应用 Serverless 的架构。IAAS - Infrastructure as a Service基础设施即服务,比如计算机存储、网络、服务器等基建设施以服务的方式提供。SAAS - Software as a Service软件即服务,比如 ERP、CRM、邮箱服务等,以软件为粒度提供服务。容器容器就是隔离了物理环境的虚拟程序执行环境,而且环境可被描述、迁移。比较热门的容器技术是 Docker。随着容器数量增多,就出现了管理容器集群的技术,比较有名的容器编排平台是 Kubernetes。容器技术是 Serverless 架构实现的一种选择,也是实现的基础。NoOps就是无人运维,比较理想主义,也许要借助 AI 的能力才能实现完全无人运维。无人运维不代表 Serverless,Serverless 可能也需要人运维(至少现在),只是开发者不再需要关心环境。DevOps笔者觉得可以理解为 “开发即运维”,毕竟出了事情,开发要被问责,而一个成熟的 DevOps 体系可以让更多的开发者承担 OP 的职责,或者与 OP 更密切的合作。回到 Serverless,未来后端开发的体验可能与前端相似:不需要关心代码运行在哪台服务器(浏览器),无需关心服务器环境(浏览器版本)、不用担心负载均衡(前端从未担心过)、中间件服务随时调用(LocalStorage、Service Worker)。前端同学对 Serverless 应该尤为激动。就拿笔者亲身经历举例吧。从做一款游戏说起笔者非常迷恋养成类游戏,养成游戏最常见的就是资源建造、收集,或者挂机时计算资源的 读秒规则。笔者在开发游戏的时候,最初是将客户端代码与服务端代码完全分成两套实现的:// … UI 部分,画出一个倒计时伐木场建造进度条const currentTime = await requestBuildingProcess();const leftTime = new Date().getTime() - currentTime;// … 继续倒计时读条// 读条完毕后,每小时木头产量 + 100,更新到客户端计时器store.woodIncrement += 100;为了游戏体验,用户可以在不刷新浏览器的情况下,看到伐木场建造进度的读条,以及 嘭 一下建造完毕,并且发现每秒钟多获得了 100 点木材!但是当伐木场 建造完成前、完成时、完成后的任意时间点刷新浏览器,都要保持逻辑的统一,而且数据需要在后端离线计算。 此时就要写后端代码了:// 每次登陆时,校验当前登陆const currentTime = new Date().getTime()// 获取伐木场当前状态if ( /* 建造中 /) { // 返回给客户端当前时间 const leftTime = building.startTime - currentTime res.body = leftTime} else { // 建造完毕 store.woodIncrement += 100}很快,建筑的种类多了起来,不同的状态、等级产量都不同,前后端分开维护成本会越来越大,我们需要做配置同步。配置同步为了做前后端配置同步,可以将配置单独托管起来前后端共用,比如新建一个配置文件,专门存储游戏信息:export const buildings = { wood: { name: “..”, maxLevel: 100, increamentPerLevel: 50, initIncreament: 100 } / .. and so on .. /};这虽然复用了配置,但前后端都有一些共同的逻辑可以复用,比如 根据建筑建造时间判断建筑状态,判断 N 秒后建筑的产量等等。 而 Serverless 带来了进一步优化的空间。在 Serverless 环境下做游戏试想一下,可以在服务器以函数粒度执行代码,我们可以这样抽象游戏逻辑:// 根据建筑建造时间判断建筑状态export const getBuildingStatusByTime = (instanceId: number, time: number) => { /**/};// 判断建筑生产量export const getBuildingProduction = (instanceId: number, lastTime: number) => { const status = getBuildingStatusByTime(instanceId, new Date().getTime()); switch (status) { case “building”: return 0; case “finished”: // 根据 (当前时间 - 上次打开时间) 每秒产量得到总产量 return; // }};// 前端 UI 层,每隔一秒调用一次 getBuildingProduction 函数,及时更新生产数据// 前端入口函数export const frontendMain = () => { //};// 后端 根据每次打开时间,调用一次 getBuildingProduction 函数并入库// 后端入口函数export const backendMain = () => { /**/};利用 PASS 服务,将前后端逻辑写在一起,将 getBuildingProduction 函数片段上传至 FAAS 服务,这样就可以同时共享前后端逻辑了!在文件夹视图下,可以做如下结构规划:.├── client # 前端入口├── server # 后端入口├── common # 共享工具函数,可以包含 80% 的通用游戏逻辑也许有人会问:前后端共享代码不止有 Serverless 才能做到。的确如此,如果代码抽象足够好,有成熟的工程方案支持,是可以将一份代码分别导出到浏览器与服务器的。但 Serverless 基于函数粒度功能更契合前后端复用代码的理念,它的出现可能会推动更广泛的前后端代码复用,这虽然不是新发明,但足够称为一个伟大的改变。前后端的视角对于前端开发者,会发现后台服务变简单了。对于后端开发者,发现服务做厚了,面临的挑战更多了。更简单的后台服务传统 ECS 服务器在租赁时,CentOS 与 AliyunOS 的环境选择就足够让人烦恼。对个人开发者而言,我们要搭建一个完整的持续集成服务是很困难的,而且面临的选择很多,让人眼花缭乱:可以在服务器安装数据库等服务,本地直联服务器的数据库进行开发。可以本地安装 Docker 连接本地数据库服务,将环境打包成镜像整体部署到服务器。将前后端代码分离,前端代码在本地开发,服务端代码在服务器开发。甚至服务器的稳定性,需要 PM2 等工具进行管理。当服务器面临攻击、重启、磁盘故障时,打开复杂的工作台或登陆 Shell 后一通操作才能恢复。这怎么让人专心把精力放在要做的事情上呢?Serverless 解决了这个问题,因为我们要上传的只是一个代码片段,不再需要面对服务器、系统环境、资源等环境问题,外部服务也有封装好的 BAAS 体系支持。实际上在 Serverless 出来之前,就有许多后端团队利用 FAAS 理念简化开发流程。为了减少写后端业务逻辑时,环境、部署问题的干扰,许多团队会将业务逻辑抽象成一个个区块(Block),对应到代码片段或 Blockly,这些区块可以独立维护、发布,最后将这些代码片段注入到主程序中,或动态加载。如果习惯了这种开发方式,那也更容易接受 Serverless。更厚的后台服务站在后台角度,事情就变得比较复杂了。相对于提供简单的服务器和容器,现在要对用户屏蔽执行环境,将服务做得更厚。笔者通过一些文章了解到,Serverless 的推行还面临着如下一些挑战:Serverless 各厂商实现种类很多,想让业务做到多云部署,需要抹平差异。成熟的 PASS 服务其实是伪 Serverless,后续该如何标准化。FAAS 冷启动需要重新加载代码、动态分配资源,导致冷启动速度很慢,除了预热,还需要经济的优化方式。对于高并发(比如双 11 秒杀)场景的应用,无需容量评估是很危险的事情,但如果真能做到完全弹性化,就省去了烦恼的容量评估。存量应用如何迁移。业界的 Serverless 服务厂商大部分都没有解决存量应用迁移的问题。Serverless 的特性导致了无状态,而复杂的互联网应用都是有状态的,因此挑战在不改变开发习惯的情况下支持状态。所幸的是,这些问题都已经在积极处理中,而且不少有了已经落地的解决方案。Serverless 给后台带来的好处远比面临的挑战多:推进前后端一体化。进一步降低 Node 写服务端代码的门槛,免除应用运营的学习成本。笔者曾经遇到过自己申请的数据库服务被迁移到其他机房而导致的应用服务中断,以后再也不需要担心了,因为数据库作为 BAAS 服务,是不需要关心在哪部署,是否跨机房,以及如何做迁移的。提高资源利用效率。杜绝应用独占资源,换成按需加载必然能减少不必要的资源消耗,而且将服务均摊到集群的每一台机器,拉平集群的 CPU 水位。降低云平台使用门槛。无需运维,灵活拓展,按价值服务,高可用,这些能力在吸引更多客户的同时,完全按需计费的特性也减少了用户开销,达到双赢。利用 Serverless 尝试服务开放笔者在公司负责一个大型 BI 分析平台建设,BI 分析平台的底层能力之一就是可视化搭建。那么可视化搭建能力该如何开放呢?现在比较容易做到的是组件开放,毕竟前端可以与后端设计相对解耦,利用 AMD 加载体系也比较成熟。现在遇到的一个挑战就是后端能力开放,因为当对取数能力有定制要求时,可能需要定制后端数据处理的逻辑。目前能做到的是利用 maven3、jdk7 搭建本地开发环境测试,如果想上线,还需要后端同学的协助。如果后端搭建一个特有的 Serverless BAAS 服务,那么就可以像前端组件一样进行线上 Coding,调试,甚至灰度发布进行预发测试。现在前端云端开发已经有了不少成熟的探索,Serverless 可以统一前后端代码在云端开发的体验,而不需要关心环境。Serverless 应用架构设计看了一些 Serverless 应用架构图,发现大部分业务都可以套用这样一张架构图:将业务函数抽象成一个个 FAAS 函数,将数据库、缓存、加速等服务抽象成 BAAS 服务。上层提供 Restful 或事件触发机制调用,对应到不同的端(PC、移动端)。想要拓展平台能力,只要在端上做开放(组件接入)与 FAAS 服务做开放(后端接入)即可。收益与挑战Serverless 带来了的收益与挑战并存,本文站在前端角度聊一聊。收益一:前端更 Focus 在前端体验技术,而不需要具备太多应用管理知识。最近看了很多前端前辈写的总结文,最大的体会就是回忆 “前端在这几年到底起到了什么作用”。我们往往会夸大自己的存在感,其实前端存在的意义就是解决人机交互问题,大部分场景下,都是一种景上添花的作用,而不是必须。回忆你最自豪的工作经历,可能是掌握了 Node 应用的运维知识、前端工程体系建设、研发效能优化、标准规范制定等,但真正对业务起效的部分,恰恰是你觉得写得最不值得一提的业务代码。前端花了太多的时间在周边技术上,而减少了很多对业务、交互的思考。即便是大公司,也难以招到既熟练使用 Nodejs,又具备丰富运维知识的人,同时还要求他前端技术精湛,对业务理解深刻,鱼和熊掌几乎不可兼得。Serverless 可以有效解决这个问题,前端同学只需要会写 JS 代码而无需掌握任何运维知识,就可以快速实现自己的整套想法。诚然,了解服务端知识是有必要的,但站在合理分工的角度,前端就应该 focus 在前端技术上。前端的核心竞争力或者带来的业务价值,并不会随着了解多一些运维知识而得到补充,相反,这会吞噬掉我们本可以带来更多业务价值的时间。语言的进化、浏览器的进化、服务器的进化,都是从复杂到简单,底层到封装的过程,而 serverless 是后端 + 运维作为一个整体的进一步封装的过程。收益二:逻辑编排带来的代码高度复用、可维护,拓展 云+端 的能力。云+端 是前端开发的下个形态,提供强大的云编码能力,或者通过插件将端打造为类似云的开发环境。其最大好处就是屏蔽前端开发环境细节,理念与 Serverless 类似。之前有不少团队尝试过利用 Graphsql 让接口 “更有弹性”,而 Serverless 则是更彻底的方案。我自己的团队就尝试过 Graphsql 方案,但由于业务非常复杂,难以用标准的模型描述所有场景的需求,因此不适合使用 Graphsql。恰恰是一套基于 Blockly 的可视化后端开发平台坚持了下来,而且取得了惊人的开发提效。这套 Blockly 通用化抽象后几乎可以由 Serverless 来代替。所以 Serverless 可以解决复杂场景下后端研发提效的问题。Serverless 在融合了云端开发后,就可以通过逻辑编排进一步可视化调整函数执行顺序、依赖关系。笔者之前在百度广告数据处理团队使用过这种平台计算离线日志,每个 MapReduce 计算节点经过可视化后,就可以轻松看出故障时哪个节点在阻塞,还可以看到最长执行链路,并为每个节点重新分配执行权重。即便逻辑编排不能解决开发的所有痛点,但在某个具体业务场景下一定可以大有作为。挑战一:Serverless 可以完全取消前端转后端的门槛?前端同学写 Node 代码最容易犯的毛病就是内存溢出。浏览器 + Tab 天然是一个用完即关的场景,UI 组件与逻辑创建与销毁也非常频繁,因此前端同学很少,也不太需要关心 GC 问题。而 GC 在后端开发场景中是一个早已养成的习惯,因此 Nodejs 程序缓存溢出是大家最关注的问题。Serverless 应用是动态加载,长时间不用就会释放的,因此一般来说不需要太担心 GC 的问题,就算内存溢出,在内存被占满前可能已经进程被释放,或者被监测到异常强制 Kill 掉。但毕竟 FAAS 函数的加载与释放完全是由云端控制的,一个常用的函数长时间不卸载也是有可能的,因此 FAAS 函数还是要注意控制副作用。所以 Serverless 虽然抹平了运维环境,但服务端基本知识还需要了解,必须意识到代码跑在前端还是后端。挑战二:性能问题Serverless 的冷启动会导致性能问题,而让业务方主动关心程序的执行频率或者性能要求,再开启预热服务又重新将研发拖入了运维的深渊中。即便是业界最成熟的亚马逊 Serverless 云服务,也无法做到业务完全不关心调用频率,就可以轻松应付秒杀场景。因此目前 Serverless 可能更适合结合合适的场景使用,而不是任何应用都强行套用 Serverless。虽然可以通过定期运行 FAAS 服务来保证程序一直 Online,但笔者认为这还是违背了 Serverless 的理念。挑战三:如何保证代码可迁移性有一张很经典的 Serverless 定位描述图:网络、存储、服务、虚拟家、操作系统、中间件、运行时、数据都不需要关心了,甚至连应用层都只需要关心其中函数部分,而不需要关心其他比如启动、销毁部分。前面总拿这点当优势,但也可以反过来认为是个劣势。 当你的代码完全依赖某个公有云环境后,你就失去了整体环境的掌控力,甚至代码都只能在特定的云平台才能运行。不同云平台提供的 BAAS 服务规范可能不同,FAAS 的入口、执行方式也可能不同,想要采用多云部署就必须克服这个问题。现在许多 Serverless 平台都在考虑做标准化,但同时也有一些自下而上的工具库抹平一些差异,比如 Serverless Framework 等。而我们写 FAAS 函数时,也尽量将与平台绑定的入口函数写得轻一些,将真正的入口放在通用的比如 main 函数中。3. 总结Serverless 的价值远比挑战大,其理念可以切实解决许多研发效能问题。但目前 Serverless 发展阶段仍处于早期,国内的 Serverless 也处于尝试阶段,而且执行环境存在诸多限制,也就是并没有完全实现 Serverless 的美好理念,因此如果什么都往上套一定会踩坑。可能在 3-5 年后,这些坑会被填平,那么你是选择加入填坑大军,还是选一个合适的场景使用 Serverless 呢?讨论地址是:精读《Serverless 给前端带来了什么》 · Issue #135 · dt-fe/weekly如果你想参与讨论,请点击这里,每周都有新的主题,周末或周一发布。前端精读 - 帮你筛选靠谱的内容。

March 11, 2019 · 3 min · jiezi

您收到一封 2019 阿里云峰会 (北京) 邀请函

摘要: 阿里云峰会(北京)开发者专场以“云原生和可见的云未来”为主题,不仅涵盖 2 场重大发布,更设置人工智能、机器学习、实时计算、云原生实践等国内外最热门的话题。我们希望和开发者一起见证云原生如此热烈的当下,云未来的各种可能性,希望您的加入!2019 年是阿里云成立的第 10 年,在过去的 10 年间,阿里云引领了国内云基础设施市场;在当下,我们希望可以和您一起分享阿里云的新战略和新思考。2019 年将是云原生在中国爆发和落地的一年,在这样的背景下,阿里将如何探索实时计算新架构?数据库的研发流程将如何演进?我们在代码智能化上又有怎样的思考和实践?云原生又将如何赋能AI、基因等各行业?【开发者专场三大亮点】亮点一阿里巴巴集团副总裁/达摩院首席数据科学家/数据库产品事业部负责人 李飞飞联合 阿里云云智能战略与合作部总经理 刘湘雯 共同畅谈开发者与可见的云未来。亮点二阿里云智能基础产品事业部研究员 周经森 发布 OpenJDK 长期支持版本 Alibaba Dragonwell亮点三重磅发布:CNCF X Alibaba 云原生技术课程免费报名报名地址:https://www.yunqi.org/goPage?page=bj_signup_mb&activeId=2&ticketTypeId=39&channelId=23【开发者专场议题】本文作者:amber涂南阅读原文本文为云栖社区原创内容,未经允许不得转载。

March 7, 2019 · 1 min · jiezi

云计算,从“资源时代”迈入“功能时代”

本文作者:张海龙,CODING 创始人兼 CEO发完开工利是之后,2019 年算是正式开始了。 2019 年经济减速的阴云笼罩了所有行业,云计算行业也难独善其身:上游供应商英特尔将自身业务的疲软归咎于”数据中心设备行业市场减速“;与此同时微软在 1 月 30 日公布的财报也低于预期:Azure 2018 年 Q4 的销售增长了 76% ,为该指标公布后的最低值;AWS 也同样饱受行业放缓的困扰,虽然有着超过 73 亿美元的收入,但是增速创 2015 年以来新低。 评论认为,云计算行业的存量市场或消耗殆尽,正式进入低潮期。我觉得所谓的寒冬并不完全是坏事,穷则思变,变则通。增速低迷迫使整个行业思考云计算在资源范畴以外的价值。《流浪地球》里对刹车时代、逃逸时代和流浪时代的设定很有意思,类比于云计算行业,我们现在应该处于“资源时代”的末期,即将进入“功能时代”。本文是我基于现在的市场环境下,对云服务未来的发展趋势作出的一些思考。“功能时代”的发动机:Serverless先定义一下两个时代:资源时代:云平台主要以提供虚拟机为主,本质上就是把服务器从企业自身的机房搬去了公用的机房,但是服务器和虚拟机的管理和维护仍然需要企业自身承担。功能时代:云平台会通过 Serverless 或 SaaS 的形式,把很多共性的功能包装成成品直接提供给客户使用,减少运维工作,企业将更专注于其核心业务逻辑。资源时代有两个阶段:虚拟机阶段和容器阶段。虚拟机阶段已经走过,用户不再需要对物理设备进行管理和维护。目前我们正在经历容器阶段:将 OS 虚拟化,此时,服务器资源已经迅速的平价化,云平台的竞争已经逐步从单纯的硬件价格竞争滑向功能层面的竞争。但是容器仍有一定门槛,需要专门的运维人员来管理,这样的服务方式依旧只适用于大型企业或者新兴科技公司。帮助相对传统的企业上云的问题依然没有解决。 而 Serverless 的出现标志着”功能时代“的到来,企业将逐步摆脱底层运维的管理负担,大幅降低云的使用门槛,给云服务行业带来质变。What is Serverless当提到 Serverless 大家脑中立刻就会联想到 AWS 的 Lamda 服务。狭义上 Serverless 的确指 Lamda 这类无需预置环境或管理服务器即可运行代码的服务,但更广义上的 Serverless 是指在用户和云服务之间搭建了一个隔离层,用户直接使用”功能“,而对其中的”云服务“无感知的一种云服务方式。在 Serverless 的环境下,云平台把自身成熟的技术和架构打包成功能性的服务提供给企业, 企业无需对底层架构进行维护和管理,直接使用相关功能或服务即可。之前备受关注的她拍小程序其实就是一个很好的 Serverless 的例子,腾讯云把天天 P 图成熟的图像识别和处理技术打包成产品直接提供给客户。她拍无需研究相应的底层技术,也无需关系图像处理服务的运维细节,只需要按用量付费即可。大公司们的 Serverless 战场在这个技术日新月异的时代,云计算行业的竞争维度已悄然变化,从资源价格战转为对服务能力的比拼。能否从业务中抽象出共性功能直接提供给客户,帮助其产品快速投入市场,是云厂商竞争的关键。自 AWS 2014 发布了 AWS Lamda 后,Serverless 便成为云服务领域最火的关键字了。几乎所有的主流云平台都在短时间内发布了相应的 Serverless 产品。 但做出完整的 Serverless 解决方案需要在硬件及软件创新上投入数十亿美元。现在 AWS、微软和谷歌都在疯狂砸钱,这样激烈的竞争也导致一些传统的或者第一梯队外的云厂商被甩得越来越远。巨头们和他们提供的 Serverless 服务为何 Serverless 会如此受到大公司的青睐?因为 Serverless 这种颠覆式的架构,在方便客户的同时,给云平台也带来了新的用户和新的利润空间。拓展新的客户就像开头提及的,云计算行业在 2018 末遭遇了第一个瓶颈期,存量市场消耗殆尽,需要找寻新的增长点。 资源时代,由于依然要管理和维护服务器,新体验与旧体验的差值有限,考虑到较高的替换成本,企业上云意愿不高。客户选择某一产品的价值考量但是 Serverless 的出现改变了这一状况。企业直接使用某项服务,无需运维投入,新体验价值极高,对于未上云的企业来说,有着巨大的吸引力。Serverless 的市场份额预计提升利润空间云平台最开始按照虚拟机来卖服务器,对服务器资源来说效率很低,75% 以上的计算资源被浪费了。容器技术普及后,按照特定环境来卖计算资源,利用率提升到 50% 左右,依然存在大量的空置。但 Serverless 允许用户以函数为单位包装代码,剩下执行的事儿完全由云平台负责,按照使用量收费,这种模式理论上可以让资源利用率达到 100% 。同样的资源在之前只能卖 1 块钱,在 Serverless 的模式下可以卖到 2 块钱到 4 块钱,对于云平台来说何乐而不为呢?企业上云的新机遇对于很多还未上云的企业来说,Serverless 同样是一个难得的新机遇,为什么这么说呢?相信大家都知道那句"Software is eating the world"在现在这个数字化的商业环境中,企业对于软件的依赖,已经达到了前所未有的高度。之前因管理和维护成本还在观望的企业,将在 Serverless 的时代迎来新的上云契机。Serverless 为企业带来的好处主要有以下三点:干掉了传统的运维,不再需要维护服务器用多少就付多少钱,不再为闲置资源付费缩短了产品交付时间,提高迭代效率正是由于以上种种优势,现在国外已经有很多大公司开始采用 Serverless 这一架构,比如:FINRA (美国金融业监管局) 每天通过 Serverless 处理超过 10 亿项股票交易证明。全球最大的在线旅游公司 Expedia 深度使用 AWS 的 Serverless 服务,月度触发量达 23 亿。对于企业内部的开发者来说,Serverless 函数及服务的架构也是极具诱惑力的。得益于 Serverless 的便利性,一个需求,仅需业务经理、产品经理和少量开发人员介入,从确定业务需求到在生产环境部署,可能只要 2 个小时即可完成。在整个过程中没有环境需要准备,可以在极短的时间完成代码并完成业务验收。但是,企业需要注意的是,Serverless 并不是万能药,在选择 Serverless 的同时也要注意相对应的风险。切换供应商的成本增加:尽管也有像 OpenFaaS 这样的开源项目在做 Serverless 的实践,但是市场仍然由主流云计算厂商主导。每家供应商提供的方案都会有些许不同,导致如果企业需要在不同的供应商(如 AWS Lamda 和 Microsoft Azure function )之间切换,会需要做大量的工作来适应新的架构。随着云平台服务的不断深入,为企业提供便捷服务的同时,也无形中增加了企业的迁移成本。在得到了不需要管理服务器的便利的同时,企业也失去了管理服务器的能力。完全依赖于云厂商提供的底层服务,企业需要承担云厂商产品不成熟或策略变动的风险。总的来说:云计算行业即将从“资源时代”进入“功能时代”,云平台将会通过 Serverless 的形式把很多共性的功能包装成成品直接提供给客户使用,减少客户上云的升级成本,同时减少运维工作,帮助企业节省出更多的精力来关注核心业务逻辑。各大云平台已经积极投入到 Serverless 功能的开发中,因为 Serverless 能够帮助云平台吸引新的客户和提高自身的利润率。对于还未上云的企业来说,Serverless 以其“低运维成本”、“实用实付”、”缩短交付周期“的特性,带来了低门槛上云的新机遇。我相信在不久的未来,购买云厂商的“功能”将成为企业的策略首选,企业可以将精力都放在核心业务核心优势上,剩下的事情,就全部交给云平台去做吧。点击一键上云,体验企业 DevOps 全流程,无缝协作,快速交付Reference: Serverless Architectures,Mike Roberts,martinfowler.com 微软多“云”转阴,Pingwest Amazon reports better than expected Q4, but lowers Q1 guidance,Techcrunch Today in Serverless and Open Source,hackernoon ...

February 22, 2019 · 1 min · jiezi

简介:Virtual Kubelet

Virtual Kubelet是Kubernetes kubelet的一个实现,它伪装成一个kubelet,用于将Kubernetes集群连接到其他API。这允许Kubernetes节点由其他服务支持,例如无服务器容器平台。架构kubelets通常如何工作一般来讲,Kubernetes kubelet为每个Kubernetes节点(Node)实现Pod和容器操作。它们作为每个节点上的代理运行,无论该节点是物理服务器还是虚拟机,并在该节点上处理Pod/容器操作。kubelets将名为PodSpec的配置作为输入,并确保PodSpec中指定的容器正在运行且运行正常。Virtual Kubelet的工作原理从Kubernetes API服务器的角度来看,Virtual Kubelet看起来像普通的kubelet,但其关键区别在于它们在其他地方调度容器,例如在云无服务器API中,而不是在节点上。下面显示了一个Kubernetes集群,其中包含一系列标准kubelet和一个Virtual Kubelet:供应商Virtual Kubelet支持各种供应商(Provider):Alibaba Cloud Elastic Container Instance (ECI)AWS FargateAzure BatchAzure Container Instances (ACI)Kubernetes Container Runtime Interface (CRI)Huawei Cloud Container Instance (CCI)Hyper.shHashiCorp NomadService Fabric MeshvSphere Integrated Containers (VIC)你还可以添加自己的供应商。这里有早前在西雅图举办的KubeCon + CloudNativeCon 2018北美大会的Virtual Kubelet视频:简介:Virtual Kubelet深入了解:Virtual KubeletVirtual Kubelet项目最近跟新了网页,快来了解一下!2019年KubeCon + CloudNativeCon中国论坛提案征集(CFP)现已开放KubeCon + CloudNativeCon 论坛让用户、开发人员、从业人员汇聚一堂,面对面进行交流合作。与会人员有 Kubernetes、Prometheus 及其他云原生计算基金会 (CNCF) 主办项目的领导,和我们一同探讨云原生生态系统发展方向。2019年中国开源峰会提案征集(CFP)现已开放在中国开源峰会上,与会者将共同合作及共享信息,了解最新和最有趣的开源技术,包括 Linux、容器、云技术、网络、微服务等;并获得如何在开源社区中导向和引领的信息。大会日期:提案征集截止日期:太平洋标准时间 2 月 15 日,星期五,晚上 11:59提案征集通知日期:2019 年 4 月 1 日会议日程通告日期:2019 年 4 月 3 日幻灯片提交截止日期:6 月 17 日,星期一会议活动举办日期:2019 年 6 月 24 至 26 日2019年KubeCon + CloudNativeCon + Open Source Summit China赞助方案出炉啦 ...

January 24, 2019 · 1 min · jiezi

Real Developer 应该参加的硬核竞赛来了!

本文由云+社区发表Labs Contest 竞赛简介君君这次又来搞大事情啦,在 Function As A Service,Serverless,PaaS 大行其道的今天,你是否已经忘记了自己动手搭建所需环境的乐趣呢?第一次使用 yum,第一次输出 phpinfo,第一次在本地虚拟化 Linux,第一次参与腾讯云的线上开发者实验室。我们有太多第一次,却因为种种原因又转身遗忘。现在,腾讯云学院+开发者实验室邀请大家重回开发本质,抛去所有辅助工具,从零到一架构自己的服务器环境,并与其它开发者一较高下!Labs Contest 竞赛规则Chapter 1: 在实验室特定环境下自主选择完成 Nginx,Apache,IIS 等 静态 WEB 环境搭建,并利用实验室 IP 地址输出“Hello Lab Contest”Chapter 2: 在实验室特定环境下自主选择完成 PHP,Node,JSP,ASP.NET,Golang ,Djiango 等环境语言搭建。并使用所搭建的环境完成一个简易表单提交系统。所用数据库包括但不限 Mysql,SQLite,Access,MangoDB 等。Chapter 3: 在实验室特定环境下自主选择完成 一份简历单页&小程序制作。简历单页必须包括但不限于 个人资料,作品展示,留言表单 提交功能。 简历单页以有单独后台页为佳,但必须实现上述三个功能。Labs Contest 竞赛奖励完成 Chapter 1:按照完成时间及完成度筛选前 30位奖励 88 代金券完成 Chapter 2:按照完成度及提交评审的代码质量筛选前 10位奖励 200 代金券及腾讯云纪念礼品完成 Chapter 3:按照完成度及提交评审的代码质量筛选前 3位奖励 600 代金券及腾讯云纪念礼品分享文章或图片到朋友圈截图发给微信号(Tcloudedu)奖励腾讯云纪念礼品(3名)介绍了这么多,如果是 Real Developer 相信已经跃跃欲试啦。如果还没看懂的话不打紧哦,我们准备了完备的竞赛视频&详情~此文已由作者授权腾讯云+社区在各渠道发布获取更多新鲜技术干货,可以关注我们腾讯云技术社区-云加社区官方号及知乎机构号

January 15, 2019 · 1 min · jiezi

云栖专辑 | 阿里开发者们的第4个感悟:自驱是最好的进步方式

2015年12月20日,云栖社区上线。2018年12月20日,云栖社区3岁。阿里巴巴常说“晴天修屋顶”。在我们看来,寒冬中,最值得投资的是学习,是增厚的知识储备。所以社区特别制作了这个专辑——分享给开发者们20个弥足珍贵的成长感悟,50本书单。多年以后,再回首2018-19年,留给我们自己的,除了寒冷,还有不断上升的技术能力与拼搏后的成就感。12月25日,自驱是最好的进步方式,不设限,综合提高自己的能力,这是我们送给开发者的第四个感悟。阿里城池:hungry and humble,永远不够好城池所带领的前端技术团队一直与云栖社区密切配合,每一场的云栖大会的精彩呈现都是大家的努力。1月6日第13届D2前端技术论坛将在杭州举办,欢迎参加。《Google、Facebook、GitHub、Babel核心成员齐聚,第13届D2前端技术论坛正式启动》。邓小明(城池)阿里云高级前端技术专家多年前端&全栈研发经验,在工程化、serverless有一些实践及落地感悟:自驱是最好的进步方式;永远不够好;不给自己设限,不限定自己的角色,综合提高自己的能力;从0-1很艰难,但也很有趣书单《基业长青》《企业IT架构转型之道阿里巴巴中台战略思想与架构实战》12月24日,从身边熟悉的开源系统开始,用过才能更好理解代码。这是我们送给开发者的第3个感悟。正研,社区HBase社群大V。在他的博文中,《HBase2.0中的Benchmark工具 — PerformanceEvaluation》、《深入解读HBase2.0新功能之高可用读Region Replic》、《深入解读HBase2.0新功能之AssignmentManagerV2》、《消灭毛刺!HBase2.0全链路offheap效果拔群》可以清晰看到经验的积累。阿里正研:开源改变世界杨文龙(正研)阿里巴巴存储技术事业部技术专家Ali-HBase内核研发负责人ApacheHBase社区Committer&PMC成员对分布式存储系统的设计、实践具备丰富的大规模生产的经验有些人一直想去学习热门开源软件的代码,但其实不如从身边熟悉的开源系统开始;因为只有用过,才能更好地理解代码,只有带着实际生产的问题去看,才能明白为什么要这样去设计架构。反过来,只有从源码级理解这个系统,才能在使用过程中避免采坑。推荐的书单《深入理解计算机系统》《HeadFirst设计模式》*12月21日,使命感与开放心态,是我们送给开发者的第2个感悟。阿里德歌:公益是一辈子的事,I’m digoal, just do it德歌,江湖人称德哥。PG大神,在社区拥有6500+位粉丝。三年来,他沉淀在社区的博文超过2000+篇。还记得社区刚成立时,有位开发者在博文后留言“我一直认为PG是小众数据库,没想到社区有这么多干货。” 三年过去,PG的地位一直在上升,云栖社区PG钉群也已经超过1000位开发者在一起交流讨论。*周正中(德歌)PostgreSQL 中国社区发起人之一,PostgreSQL 象牙塔发起人之一,DBA+社群联合发起人之一,10余项数据库相关专利,现就职于阿里云数据库内核技术组。学习第一要有使命感,第二要有开放的心态。使命感是技术为业务服务,结合业务一起创造社会价值,有使命感才能让你坚持下去,遇到困难时不容易被打倒。开放是在扎实的技术功底之上,跳出纯粹的技术从生态进行思考,要埋头苦干也要抬头看路。比如行业生态中重叠部分,盟友与竞争关系,问题及补齐办法等,同时也要密切关注国家和国际形势,分析背后原因,在未来技术方向决策上避免逆流行舟。推荐的书单:《PostgreSQL实战》*12月20日,场景中学习,这是我们送给开发者的第1个感悟。阿里毕玄:程序员的成长路线在这篇《程序员的成长路线》里,阿里基础设施负责人毕玄结合自己的经历跟大家讲述了他在各个角色上成长的感受。在他的职业经历中,在成长方面经历了技术能力的成长、架构能力的成长,以及现在作为一个在修炼中的技术 Leader 的成长。其中技术能力和架构能力的成长是所有程序员都很需要的,值得所有正为职业发展而迷茫的技术同学细细品味。*林昊(毕玄)阿里基础设施负责人阿里巴巴HSF、T4创始人,HBase负责人主导阿里电商分布式应用架构、异地多活架构、资源弹性架构升级程序员,要寻找甚至创造场景来学习相应的技术能力。正如学Java通讯框架,尝试基于BIO/NIO写一个,然后对比Mina/Netty,看看为什么不一样;学Java的内存管理,尝试写程序去控制GC的行为。书籍外,更建议翻看源码,结合场景才能真正理解和学会。我的职业经历是技术能力成长、架构能力成长和正在修炼中的技术Leader的成长,三条路线都可发展,没有孰优孰劣,兴趣、个人优势仍是最重要的。出版的图书:《OSGi原理与最佳实践》《分布式Java应用:基础与实践》推荐的书单:《硅谷之谜》《智能时代:大数据与智能革命重新定义未来》预计更新到1月20日,欢迎收藏。本文作者:云篆阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 25, 2018 · 1 min · jiezi

开源 serverless 产品原理剖析 - Kubeless

背景Serverless 架构的出现让开发者不用过多地考虑传统的服务器采购、硬件运维、网络拓扑、资源扩容等问题,可以将更多的精力放在业务的拓展和创新上。随着 serverless 概念的深入人心,各大云计算厂商纷纷推出了各自的 serverless 产品,其中比较有代表性的有 AWS lambda、Azure Function、Google Cloud Functions、阿里云函数计算等。另外,CNCF 也于 2016 年创立了 Serverless Working Group,它致力于 cloud native 和 serverless 技术的结合。下图是 CNCF serverless 全景图,它将这些产品分成了工具型、安全型、框架型和平台型等类别。同时,容器以及容器编排工具的出现,大大降低了 serverless 产品的开发成本,促进了一大批优秀开源 serverless 产品的诞生,它们大多构建于 kubernetes 之上,如下图所示。Kubeless 简介本文将要介绍的 kubeless 便是这些开源 serverless 产品的典型代表。根据官方的定义,kubeless 是 kubernetes native 的无服务计算框架,它可以让用户在 kubernetes 之上使用 FaaS 构建高级应用程序。从 CNCF 视角,kubeless 属于平台型产品。Kubless 有三个核心概念:Functions - 代表需要被执行的用户代码,同时包含运行时依赖、构建指令等信息;Triggers - 代表和函数关联的事件源。如果把事件源比作生产者,函数比作执行者,那么触发器就是联系两者的桥梁;Runtime - 代表函数运行时所依赖的环境。原理剖析本章节将以 kubeless 为例介绍 serverless 产品需要具备的基本能力,以及 kubeless 是如何利用 K8s 现有功能来实现它们的。这些基本能力包括:敏捷构建 - 能够基于用户提交的源码迅速构建可执行的函数,简化部署流程;灵活触发 - 能够方便地基于各类事件触发函数的执行,并能方便快捷地集成新的事件源;自动伸缩 - 能够根据业务需求,自动完成扩容缩容,无须人工干预。本文所做的调研基于kubeless v1.0.0和k8s 1.13。敏捷构建CNCF 对函数生命周期的定义如下图所示。用户只需提供源码和函数说明,构建部署等工作通常由 serverless 平台完成。 因此,基于用户提交的源码迅速构建可执行函数是 serverless 产品必须具备的基础能力。在 kubeless 里,创建函数非常简单:kubeless function deploy hello –runtime python2.7 \ –from-file test.py \ –handler test.hello该命令各参数含义如下:hello:将要部署的函数名称;–runtime python2.7: 指定使用 python 2.7 作为运行环境。Kubeless 可供选择的运行环境请参考链接 runtimes。–from-file test.py:指定函数源码文件(支持 zip 格式)。–handler test.hello:指定使用 test.py 中的 hello 方法处理请求。函数资源与 K8s OperatorKubeless 函数是一个自定义 K8s 对象,本质上是 k8s operator。k8s operator 原理如下图所示:下面以 kubeless 函数为例,描述 K8s operator 的一般工作流程:使用 k8s 的 CustomResourceDefinition(CRD) 定义资源,这里创建了一个名为functions.kubeless.io的 CRD 来代表 kubeless 函数;创建一个 controller 监听自定义资源的 ADD、UPDATE、DELETE 事件并绑定 hander。这里创建了一个名为function-controller的 CRD controller,该 controller 会监听针对 function 的 ADD、UPDATE、DELETE 事件,并绑定 handler(参阅 AddEventHandler);用户执行创建、更新、删除自定义资源的命令;Controller 根据监听到的事件调用相应的 handler。除了函数外,下文将要介绍的 trigger 也是一个 k8s operator。函数构成Kubeless 的 function-controller监听到针对 function 的 ADD 事件后,会触发相应 handler 创建函数。一个函数由若干 K8s 对象组成,包括 ConfigMap、Service、Deployment、Pod 等,其结构如下图所示:ConfigMap函数中的 ConfigMap 用于描述函数源码和依赖。apiVersion: v1data: handler: test.hello # 函数依赖的第三方 python 库 requirements.txt: | kubernetes==2.0.0 # 函数源码 test.py: | def hello(event, context): print event return event[‘data’]kind: ConfigMapmetadata: labels: created-by: kubeless function: hello # 该 ConfigMap 名称 name: hello namespace: default…Service函数中的 Service 用于描述该函数的访问方式。该 Service 会与执行 function 逻辑的 Pods 相关联,类型是 ClusterIP。apiVersion: v1kind: Servicemetadata: labels: created-by: kubeless function: hello # 该 Service 名称 name: hello namespace: default …spec: clusterIP: 10.109.2.217 ports: - name: http-function-port port: 8080 protocol: TCP targetPort: 8080 selector: created-by: kubeless function: hello # Service 类型 type: ClusterIP…Deployment函数中的 Deployment 用于编排执行函数逻辑的 Pods,通过它可以描述函数期望的个数。apiVersion: extensions/v1beta1kind: Deploymentmetadata: labels: created-by: kubeless function: hello name: hello namespace: default …spec: # 指定函数期望的个数 replicas: 1…Pod函数中的 Pod 包含真正执行函数逻辑的容器。VolumesPod 中的 volumes 段指定了该函数的 ConfigMap。这会将 ConfigMap 中的源码和依赖添加到 volumeMounts.mountPath 指定的目录里面。从容器视角来看,文件路径为/src/test.py和 /src/requirements。… volumeMounts: - mountPath: /kubeless name: hello - mountPath: /src name: hello-depsvolumes:- emptyDir: {} name: hello- configMap: defaultMode: 420 name: hello…Init ContainerPod 中的 Init Container 主要作用如下:将源码和依赖文件拷贝到指定目录;安装第三方依赖。Func ContainerPod 中的 Func Container 会加载 Init Container 准备好的源码和依赖并执行函数。不同 runtime 加载代码的方式大同小异,可参考 kubeless.py,Handler.java。小结Kubeless 通过综合运用 K8s 中的多种组件以及利用各语言的动态加载能力实现了从用户源码到可执行的函数的构建逻辑;考虑了函数运行的安全性,通过 Security Context 机制限制容器中的进程以非 root 身份运行。灵活触发一款成熟的 serverless 产品需要具备灵活触发能力,以满足事件源的多样性需求,同时需要能够方便快捷地接入新事件源。CNCF 将函数的触发方式分成了如下图所示的几种类别,关于它们的详细介绍可参考链接 Function Invocation Types。对于 kubeless 的函数,最简单的触发方式是使用 kubeless CLI,另外还支持通过各种触发器。下表展示了 kubeless 函数目前支持的触发方式以及它们所属的类别。触发方式类别kubeless CLISynchronous Req/RepHttp TriggerSynchronous Req/RepCronjob TriggerJob (Master/Worker)Kafka TriggerAsync Message QueueNats TriggerAsync Message QueueKinesis TriggerMessage Stream下图展示了 kubeless 函数部分触发方式的原理:HTTP trigger如果希望通过发送 HTTP 请求触发函数执行,需要为函数创建 HTTP 触发器。 Kubeless 利用 K8s ingress 机制实现了 http trigger。Kubeless 创建了一个名为httptriggers.kubeless.io的 CRD 来代表 http trigger 对象。同时,kubeless 包含一个名为http-trigger-controller的 CRD controller,它会持续监听针对 http trigger 和 function 的 ADD、UPDATE、DELETE 事件,并执行对应的操作。以下命令将为函数 hello 创建一个名为http-hello的 http trigger,并指定选用 nginx 作为 gateway。kubeless trigger http create http-hello –function-name hello –gateway nginx –path echo –hostname example.com该命令会创建如下 ingress 对象,可以参考 CreateIngress 深入了解 ingress 的创建逻辑。apiVersion: extensions/v1beta1kind: Ingressmetadata: # 该 Ingress 的名字,即创建 http trigger 时指定的 name name: http-hello …spec: rules: - host: example.com http: paths: - backend: # 指向 kubeless 为函数 hello 创建的 ClusterIP 类型的 Service serviceName: hello servicePort: 8080 path: /echoIngress 只是用于描述路由规则,要让规则生效、实现请求转发,集群中需要有一个正在运行的 ingress controller。可供选择的 ingress controller 有 Contour、F5 BIG-IP Controller for Kubernetes、Kong Ingress Controllerfor Kubernetes、NGINX Ingress Controller for Kubernetes、Traefik 等。这种路由规则描述和路由功能实现相分离的思想很好地提现了 K8s 始终坚持的需求和供给分离的设计理念。上文中的命令在创建 trigger 时指定了 nginx 作为 gateway,因此需要部署一个 nginx-ingress-controller。该 controller 的基本工作原理如下:以 pod 的形式运行在独立的命名空间中;以 hostPort 的形式暴露出来供外界访问;内部运行着一个 nginx 实例;监听和 ingress、service 等资源相关的事件。如果发现这些事件最终会影响到路由规则,ingress controller 会采用向 Lua hander 发送新的 endpoints 列表或者直接修改 nginx.conf 并 reload nginx 等手段达到更新路由规则的目的。想要更深入地了解 nginx-ingress-controller 的工作原理可参考文章 how-it-works。完成上述工作后,我们便可以通过发送 HTTP 请求触发函数 hello 的执行:HTTP 请求首先会由 nginx-ingress-controller 中的 nginx 处理;Nginx 根据 nginx.conf 中的路由规则将请求转发给函数对应的 service;最后,请求会转发至挂载在 service 后的某个函数进行处理。样例如下:curl –data ‘{“Another”: “Echo”}’ \ –header “Host: example.com” \ –header “Content-Type:application/json” \ example.com/echo# 函数返回{“Another”: “Echo”}Cronjob trigger如果希望定期触发函数执行,需要为函数创建 cronjob 触发器。K8s 支持通过 CronJob 定期运行任务,kubeless 利用这个特性实现了 cronjob trigger。Kubeless 创建了一个名为cronjobtriggers.kubeless.io的 CRD 来代表 cronjob trigger 对象。同时,kubeless 包含一个名为cronjob-trigger-controller的 CRD controller,它会持续监听针对 cronjob trigger 和 function 的 ADD、UPDATE、DELETE 事件,并执行对应的操作。以下命令将为函数 hello 创建一个名为scheduled-invoke-hello的 cronjob trigger,该触发器每分钟会触发函数 hello 执行一次。kubeless trigger cronjob create scheduled-invoke-hello –function=hello –schedule="*/1 * * * *“该命令会创建如下 CronJob 对象,可以参考 EnsureCronJob 深入了解 CronJob 的创建逻辑。apiVersion: batch/v1beta1kind: CronJobmetadata: # 该 CronJob 的名字,即创建 cronjob trigger 时指定的 name name: scheduled-invoke-hello …spec: # 该 CronJob 的执行计划,即创建 cronjob trigger 时指定的 schedule schedule: */1 * * * * … jobTemplate: spec: activeDeadlineSeconds: 180 template: spec: containers: - args: - curl - -Lv # HTTP headers,包含 event-id、event-time、event-type、event-namespace 等信息 - ’ -H “event-id: xxx” -H “event-time: yyy” -H “event-type: application/json” -H “event-namespace: cronjobtrigger.kubeless.io”’ # kubeless 会为 function 创建一个 ClusterIP 类型的 Service # 可以根据 service 的 name、namespace 拼出 endpoint - http://hello.default.svc.cluster.local:8080 image: kubeless/unzip name: trigger restartPolicy: Never …自定义 trigger如果发现 kubeless 默认提供的触发器无法满足业务需求,可以自定义新的触发器。新触发器的构建流程如下:为新的事件源创建一个 CRD 来描述事件源触发器;在自定义资源对象的 spec 里描述该事件源的属性,例如 KafkaTriggerSpec、HTTPTriggerSpec;为该 CRD 创建一个 CRD controller。该 controller 需要持续监听针对事件源触发器和 function 的 CRUD 操作并作出正确的处理。例如,controller 监听到 function 的删除事件,需要把和该 function 关联的触发器一并删掉;当事件发生时,触发关联函数的执行。我们可以看到,自定义 trigger 的流程遵循了 K8s Operator 设计模式。小结Kubeless 提供了一些基本常用的触发器,如果有其他事件源也可以通过自定义触发器接入;不同事件源的接入方式不同,但最终都是通过访问函数 ClusterIP 类型的 service 触发函数执行。自动伸缩K8s 通过 Horizontal Pod Autoscaler 实现 pod 的自动水平伸缩。Kubeless 的 function 通过 K8s deployment 部署运行,因此天然可以利用 HPA 实现自动伸缩。度量数据获取自动伸缩的第一步是要让 HPA 能够获取度量数据。目前,kubeless 中的函数支持基于 cpu 和 qps 这两种指标进行自动伸缩。下图展示了 HPA 获取这两种度量数据的途径。内置度量指标 cpuCPU 使用率属于内置度量指标,对于这类指标 HPA 可以通过 metrics API 从 Metrics Server 中获取数据。Metrics Server 是 Heapster 的继承者,它可以通过kubernetes.summary_api从 Kubelet、cAdvisor 中获取度量数据。自定义度量指标 qpsQPS 属于自定义度量指标,想要获取这类指标的度量数据需要完成下列步骤。部署用于存储度量数据的系统,这里选择已经被纳入 CNCF 的 Prometheus。Prometheus 是一套开源监控&告警&时序数据解决方案,并且被 DigitalOcean、Red Hat、SUSE 和 Weaveworks 这些 cloud native 领导者广泛使用;采集度量数据,并写入部署好的 Prometheus 中。Kubeless 提供的函数框架会在函数每次被调用时,将下列度量数据 function_duration_seconds、function_calls_total、function_failures_total 写入 Prometheus(可参考 python 样例)。部署实现了 custom metrics API 的 custom API server。这里,因为度量数据被存入了 Prometheus,因此选择部署 k8s-prometheus-adapter,它可以从 Prometheus 中获取度量数据。完成上述步骤后,HPA 就可以通过 custom metrics API 从 Prometheus Adapter 中获取 qps 度量数据。详细配置步骤可参考文章 kubeless-autoscaling。K8s 度量指标简介有时基于 cpu 和 qps 这两种度量指标对函数进行自动伸缩还远远不够。如果希望基于其它度量指标,需要了解 K8s 定义的度量指标类型及其获取方式。目前,K8s 1.13 版本支持的度量指标类型如下:准备好相应的度量数据和获取数据的组件,HPA 就能基于它们对函数进行自动伸缩。更多关于 K8s 度量指标的介绍可参考文章 hpa-external-metrics。度量数据使用知道了 HPA 获取度量数据的途径后,下面描述 HPA 如何基于这些数据对函数进行自动伸缩。基于 cpu 使用率假设已经存在一个名为 hello 的函数,以下命令将为该函数创建一个基于 cpu 使用率的 HPA,它将运行该函数的 pod 数量控制在 1 到 3 之间,并通过增加或减少 pod 个数使得所有 pod 的平均 cpu 使用率维持在 70%。kubeless autoscale create hello –metric=cpu –min=1 –max=3 –value=70Kubeless 使用的是 autoscaling/v2alpha1 版本的 HPA API,该命令将要创建的 HPA 如下:kind: HorizontalPodAutoscalerapiVersion: autoscaling/v2alpha1metadata: name: hello namespace: default labels: created-by: kubeless function: hellospec: scaleTargetRef: kind: Deployment name: hello minReplicas: 1 maxReplicas: 3 metrics: - type: Resource resource: name: cpu targetAverageUtilization: 70该 HPA 计算目标 pod 数量的公式如下:TargetNumOfPods = ceil(sum(CurrentPodsCPUUtilization) / Target)基于 qps以下命令将为函数 hello 创建一个基于 qps 的 HPA,它将运行该函数的 pod 数量控制在 1 到 5 之间,并通过增加或减少 pod 个数确保所有挂在服务 hello 后的 pod 每秒能处理的请求次数之和达到 2000。kubeless autoscale create hello –metric=qps –min=1 –max=5 –value=2k该命令将要创建的 HPA 如下:kind: HorizontalPodAutoscalerapiVersion: autoscaling/v2alpha1metadata: name: hello namespace: default labels: created-by: kubeless function: hellospec: scaleTargetRef: kind: Deployment name: hello minReplicas: 1 maxReplicas: 5 metrics: - type: Object object: metricName: function_calls target: apiVersion: autoscaling/v2beta1 kind: Service name: hello targetValue: 2k基于多项指标如果计划基于多项度量指标对函数进行自动伸缩,需要直接为运行 function 的 deployment 创建 HPA。使用如下 yaml 文件可以为函数 hello 创建一个名为hello-cpu-and-memory的 HPA,它将运行该函数的 pod 数量控制在 1 到 10 之间,并尝试让所有 pod 的平均 cpu 使用率维持在 50%,平均 memory 使用量维持在 200MB。对于多项度量指标,K8s 会计算出每项指标需要的 pod 数量,取其中的最大值作为最终的目标 pod 数量。kind: HorizontalPodAutoscalerapiVersion: autoscaling/v2alpha1metadata: name: hello-cpu-and-memory namespace: default labels: created-by: kubeless function: hellospec: scaleTargetRef: kind: Deployment name: hello minReplicas: 1 maxReplicas: 10 metrics: - type: Resource resource: name: cpu targetAverageUtilization: 50 - type: Resource resource: name: memory targetAverageValue: 200Mi自动伸缩策略一个理想的自动伸缩策略应当处理好下列场景:当负载激增时,函数能迅速扩展以应对突发流量;当负载下降时,函数能立即收缩以节省资源消耗;具备抗噪声干扰能力,能够精确计算出目标容量;能够避免自动伸缩过于频繁造成系统抖动。Kubeless 依赖的 HPA 充分考虑了上述情形,不断改进和完善其使用的自动伸缩策略。下面以 K8s 1.13 版本为例描述该策略。如果想要更加深入地了解策略原理请参考链接 horizontal。HPA 每隔一段时间会根据获取的度量数据同步一次和该 HPA 关联的 RC / Deployment 中的 pod 个数,时间间隔通过 kube-controller-manager 的参数–horizontal-pod-autoscaler-sync-period指定,默认为 15s。在每一次同步过程中,HPA 需要经历如下图所示的计算流程。计算目标副本数分别计算 HPA 列表中每项指标需要的 pod 数量,记为 replicaCountProposal。选择其中的最大值作为 metricDesiredReplicas。在计算每项指标的 replicaCountProposal 过程中会考虑下列因素:允许目标度量值和实际度量值存在一定程度的误差,如果在误差范围内直接使用 currentReplicas 作为 replicaCountProposal。这样做是为了在可接受范围内避免伸缩过于频繁造成系统抖动,该误差值可以通过 kube-controller-manager 的参数–horizontal-pod-autoscaler-tolerance指定,默认值是 0.1。当一个 pod 刚刚启动时,该 pod 反映的度量值往往不是很准确,HPA 会将这种 pod 视为 unready。在计算度量值时,HPA 会跳过处于 unready 状态的 pod。这样做是为了消除噪声干扰,可以通过 kube-controller-manager 的参数–horizontal-pod-autoscaler-cpu-initialization-period(默认为 5 分钟)和–horizontal-pod-autoscaler-initial-readiness-delay(默认为 30 秒)调整 pod 被认为处于 unready 状态的时间。平滑目标副本数将最近一段时间计算出的 metricDesiredReplicas 记录下来,取其中的最大值作为 stabilizedRecommendation。这样做是为了让缩容过程变得平滑,消除度量数据异常波动造成的影响。该时间段可以通过参数–horizontal-pod-autoscaler-downscale-stabilization-window指定,默认为 5 分钟。规范目标副本数限制 desiredReplicas 最大为 currentReplicas * scaleUpLimitFactor,这样做是为了防止因 采集到了“虚假的”度量数据造成扩容过快。目前 scaleUpLimitFactor 无法通过参数设定,其值固定为 2。限制 desiredReplicas 大于等于 hpaMinReplicas,小于等于 hpaMaxReplicas。执行扩容缩容操作如果通过上述步骤计算出的 desiredReplicas 不等于 currentReplicas,则“执行”扩容缩容操作。这里所说的执行只是将 desiredReplicas 赋值给 RC / Deployment 中的 replicas,pod 的创建销毁会由 kube-scheduler 和 worker node 上的 kubelet 异步完成的。小结Kubeless 提供的自动伸缩功能是对 K8s HPA 的简单封装,避免了将创建 HPA 的复杂细节直接暴露给用户。Kubeless 目前提供的度量指标过少,功能过于简单。如果用户希望基于新的度量指标、综合多项度量指标或者调整自动伸缩的效果,需要深入了解 HPA 的细节。目前 HPA 的扩容缩容策略是基于既成事实被动地调整目标副本数,还无法根据历史规律预测性地进行扩容缩容。总结Kubeless 基于 K8s 提供了较为完整的 serverless 解决方案,但和一些商业 serverless 产品还存在一定差距:Kubeless 并未在镜像拉取、代码下载、容器启动等方面做过多优化,导致函数冷启动时间过长;Kubeless 并未过多考虑多租户的问题,如果希望多个用户的函数运行在同一个集群里,还需要进行二次开发。本文作者:吴波bruce_wu阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

December 3, 2018 · 6 min · jiezi

无服务器架构(Serverless Architectures):什么是 Serverless

译注:为了便于对照参考,“Serverless”、“BaaS” 等术语文中不做翻译。原文很长,这里分成上下两篇。翻译过程在 GitHub 上进行。原文:https://martinfowler.com/articles/serverless.html 作者:Mike Roberts无服务器架构(Serverless architectures)是指一个应用大量依赖第三方服务(后端即服务,Backend as a Service,简称“BaaS”),或者把代码交由托管的、短生命周期的容器中执行(函数即服务,Function as a Service,简称“FaaS”)。现在最知名的 FaaS 平台是 AWS Lambda。把这些技术和单页应用等相关概念相结合,这样的架构无需维护传统应用中永远保持在线的系统组件。Serverless 架构的长处是显著减少运维成本、复杂度、以及项目起步时间,劣势则在于更加依赖平台供应商和现阶段仍有待成熟的支持环境。引言无服务器计算(Severless computing,简称 Serverless)现在是软件架构圈中的热门话题,三大云计算供应商(Amazon、Google 和 Microsoft)都在大力投入这个领域,涌现了不计其数的相关书籍、开源框架、商业产品、技术大会。到底什么是 Serverless?它有什么长处/短处?我希望通过本文对这些问题提供一些启发。开篇我们先来看看 Serverless 是什么,之后我会尽我所能中立地谈谈它的优势和缺点。什么是 Serverless就像软件行业中的很多趋势一样,Serverless 的界限并不是特别清晰,尤其是它还涵盖了两个互相有重叠的概念:Serverless 最早用于描述那些大部分或者完全依赖于第三方(云端)应用或服务来管理服务器端逻辑和状态的应用,这些应用通常是富客户端应用(单页应用或者移动端 App),建立在云服务生态之上,包括数据库(Parse、Firebase)、账号系统(Auth0、AWS Cognito)等。这些服务最早被称为 “(Mobile) Backend as a Service”,下文将对此简称为 “BaaS”。Serverless 还可以指这种情况:应用的一部分服务端逻辑依然由开发者完成,但是和传统架构不同,它运行在一个无状态的计算容器中,由事件驱动、生命周期很短(甚至只有一次调用)、完全由第三方管理(感谢 ThoughtWorks 在他们最近的“技术观察”中对此所做的定义)。这种情况称为 Functions as a service / FaaS。AWS Lambda 是目前的热门 FaaS 实现之一,下文将对此简称为 “FaaS”。【边栏注释:“Serverless” 术语的起源】本文将主要聚焦于 FaaS,不仅仅因为它是 Serverless 中最新也最热门的领域,更重要的是它和我们传统技术架构思路的显著不同。BaaS 和 FaaS 在运维层面有类似之处(都无需管理硬件资源),并且也经常配合使用。主流的云服务商都会提供一套“Serverless 全家桶”,囊括了 BaaS 和 FaaS 产品——例如 Amazon 的 Serverless 产品介绍,Google 的 Firebase 服务也紧密集成了 Google Cloud Functions。对小公司而言这两个领域也有交叉,Auth0 最初是一个 BaaS 产品,提供用户管理的各种服务,他们后来创建了配套的 FaaS 服务 Webtask,并且将此概念进一步延伸推出了 Extend,支持其他 BaaS 和 SaaS 公司能够轻松地在现有产品中加入 FaaS 能力。一些示例界面驱动的应用(UI-driven applications)我们来设想一个传统的三层 C/S 架构,例如一个常见的电子商务应用(比如在线宠物商店),假设它服务端用 Java,客户端用 HTML/JavaScript:在这个架构下客户端通常没什么功能,系统中的大部分逻辑——身份验证、页面导航、搜索、交易——都在服务端实现。把它改造成 Serverless 架构的话会是这样:这是张大幅简化的架构图,但还是有相当多变化之处:我们移除了最初应用中的身份验证逻辑,换用一个第三方的 BaaS 服务。另一个 BaaS 示例:我们允许客户端直接访问一部分数据库内容,这部分数据完全由第三方托管(如 AWS Dynamo),这里我们会用一些安全配置来管理客户端访问相应数据的权限。前面两点已经隐含了非常重要的第三点:先前服务器端的部分逻辑已经转移到了客户端,如保持用户 Session、理解应用的 UX 结构(做页面导航)、获取数据并渲染出用户界面等等。客户端实际上已经在逐步演变为单页应用。还有一些任务需要保留在服务器上,比如繁重的计算任务或者需要访问大量数据的操作。这里以“搜索”为例,搜索功能可以从持续运行的服务端中拆分出来,以 FaaS 的方式实现,从 API 网关(后文做详细解释)接收请求返回响应。这个服务器端函数可以和客户端一样,从同一个数据库读取产品数据。我们原始的服务器端是用 Java 写的,而 AWS Lambda(假定我们用的这家 FaaS 平台)也支持 Java,那么原先的搜索代码略作修改就能实现这个搜索函数。最后我们还可以把“购买”功能改写为另一个 FaaS 函数,出于安全考虑它需要在服务器端,而非客户端实现。它同样经由 API 网关暴露给外部使用。消息驱动的应用(Message-driven applications)再举一个后端数据处理服务的例子。假设你在做一个需要快速响应 UI 的用户中心应用,同时你又想捕捉记录所有的用户行为。设想一个在线广告系统,当用户点击了广告你需要立刻跳转到广告目标,同时你还需要记录这次点击以便向广告客户收费(这个例子并非虚构,我的一位前同事最近就在做这项重构)。传统的架构会是这样:“广告服务器”同步响应用户的点击,同时发送一条消息给“点击处理应用”,异步地更新数据库(例如从客户的账户里扣款)。在 Serverless 架构下会是这样:这里两个架构的差异比我们上一个例子要小很多。我们把一个长期保持在内存中待命的任务替换为托管在第三方平台上以事件驱动的 FaaS 函数。注意这个第三方平台提供了消息代理和 FaaS 执行环境,这两个紧密相关的系统。解构 “Function as a Service”我们已经提到多次 FaaS 的概念,现在来挖掘下它究竟是什么含义。先来看看 Amazon 的 Lambda 产品简介:通过 AWS Lambda,无需配置或管理服务器(1)即可运行代码。您只需按消耗的计算时间付费 – 代码未运行时不产生费用。借助 Lambda,您几乎可以为任何类型的应用程序或后端服务(2)运行代码,而且全部无需管理。只需上传您的代码,Lambda 会处理运行(3)和扩展高可用性(4)代码所需的一切工作。您可以将您的代码设置为自动从其他 AWS 服务(5)触发,或者直接从任何 Web 或移动应用程序(6)调用。本质上 FaaS 就是无需配置或管理你自己的服务器系统或者服务器应用即可运行后端代码,其中第二项——服务器应用——是个关键因素,使其区别于现今其他一些流行的架构趋势如容器或者 PaaS(Platform as a Service)。回顾前面点击处理的例子,FaaS 替换掉了点击处理服务器(可能跑在一台物理服务器或者容器中,但绝对是一个独立的应用程序),它不需要服务器,也没有一个应用程序在持续运行。FaaS 不需要代码基于特定的库或框架,从语言或环境的层面来看 FaaS 就是一个普通的应用程序。例如 AWS Lambda 支持 JavaScript、Python 以及任意 JVM 语言(Java、Clojure、Scala 等),并且你的 FaaS 函数还可以调用任何一起部署的程序,也就是说实际上你可以用任何能编译为 Unix 程序的语言(稍后我们会讲到 Apex)。FaaS 也有一些不容忽视的局限,尤其是牵涉到状态和执行时长问题,这些我们稍后详谈。再次回顾一下点击处理的例子——代码迁移到 FaaS 唯一需要修改的是 main 方法(启动)的部分,删掉即可,也许还会有一些上层消息处理的代码(实现消息监听界面),不过这很可能只是方法签名上的小改动。所有其他代码(比如那些访问数据库的)都可以原样用在 FaaS 中。既然我们没有服务器应用要执行,部署过程也和传统的方式大相径庭——把代码上传到 FaaS 平台,平台搞定所有其他事情。具体而言我们要做的就是上传新版的代码(zip 文件或者 jar 包)然后调用一个 API 来激活更新。横向扩展是完全自动化、弹性十足、由 FaaS 平台供应商管理的。如果你需要并行处理 100 个请求,不用做任何处理系统可以自然而然地支持。FaaS 的“运算容器”会在运行时按需启动执行函数,飞快地完成并结束。回到我们的点击处理应用,假设某个好日子我们的客户点击广告的数量有平日的十倍之多,我们的点击处理应用能承载得住么?我们写的代码是否支持并行处理?支持的话,一个运行实例能够处理这么多点击量吗?如果环境允许多进程执行我们能自动支持或者手动配置支持吗?以 FaaS 实现你的代码需要一开始就以并行执行为默认前提,但除此之外就没有其他要求了,平台会完成所有的伸缩性需求。FaaS 中的函数通常都由平台指定的一些事件触发。在 AWS 上有 S3(文件)更新、时间(定时任务)、消息总线(Kinesis)消息等,你的函数需要指定监听某个事件源。在点击处理器的例子中我们有个假设是已经采用了支持 FaaS 订阅的消息代理,如果没有的话这部分也需要一些代码量。大部分的 FaaS 平台都支持 HTTP 请求触发函数执行,通常都是以某种 API 网关的形式实现(如 AWS API Gateway,Webtask)。我们在宠物商店的例子中就以此来实现搜索和购买功能。状态当牵涉到本地(机器或者运行实例)状态时 FaaS 有个不能忽视的限制。简单点说就是你需要接受这么一个预设:函数调用中创建的所有中间状态或环境状态都不会影响之后的任何一次调用。这里的状态包括了内存数据和本地磁盘存储数据。从部署的角度换句话说就是 FaaS 函数都是无状态的(Stateless)。这对于应用架构有重大的影响,无独有偶,“Twelve-Factor App” 的概念也有一模一样的要求。在此限制下的做法有多种,通常这个 FaaS 函数要么是天然无状态的——纯函数式地处理输入并且输出,要么使用数据库、跨应用缓存(如 Redis)或者网络文件系统(如 S3)来保存需要进一步处理的数据。执行时长FaaS 函数可以执行的时间通常都是受限的,目前 AWS Lambda 函数执行最长不能超过五分钟,否则会被强行终止。这意味着某些需要长时间执行的任务需要调整实现方法才能用于 FaaS 平台,例如你可能需要把一个原先长时间执行的任务拆分成多个协作的 FaaS 函数来执行。启动延迟目前你的 FaaS 函数响应请求的时间会受到大量因素的影响,可能从 10 毫秒到 2 分钟不等。这听起来很糟糕,不过我们来看看具体的情况,以 AWS Lambda 为例。如果你的函数是 JavaScript 或者 Python 的,并且代码量不是很大(千行以内),执行的消耗通常在 10 到 100 毫秒以内,大函数可能偶尔会稍高一些。如果你的函数实现在 JVM 上,会偶尔碰到 10 秒以上的 JVM 启动时间,不过这只会在两种情况下发生:你的函数调用触发比较稀少,两次调用间隔超过 10 分钟。流量突发峰值,比如通常每秒处理 10 个请求的任务在 10 秒内飙升到每秒 100 个。前一种情况可以用个 hack 来解决:每五分钟 ping 一次给函数保持热身。这些问题严重么?这要看你的应用类型和流量特征。我先前的团队有一个 Java 的异步消息处理 Lambda 应用每天处理数亿条消息,他们就完全不担心启动延迟的问题。如果你要写的是一个低延时的交易程序,目前而言肯定不会考虑 FaaS 架构,无论你是用什么语言。不论你是否认为你的应用会受此影响,都应该以生产环境级别的负载测试下实际性能情况。如果目前的情况还不能接受的话,可以几个月后再看看,因为这也是现在的 FaaS 平台供应商们主要集中精力在解决的问题。API 网关我们前面还碰到过一个 FaaS 的概念:“API 网关”。API 网关是一个配置了路由的 HTTP 服务器,每个路由对应一个 FaaS 函数,当 API 网关收到请求时它找到匹配请求的路由,调用相应的 FaaS 函数。通常 API 网关还会把请求参数转换成 FaaS 函数的调用参数。最后 API 网关把 FaaS 函数执行的结果返回给请求来源。AWS 有自己的一套 API 网关,其他平台也大同小异。除了纯粹的路由请求,API 网关还会负责身份认证、输入参数校验、响应代码映射等,你可能已经敏锐地意识到这是否合理,如果你有这个考虑的话,我们待会儿就谈。另一个应用 API 网关加 FaaS 的场景是创建无服务器的 http 前端微服务,同时又具备了 FaaS 函数的伸缩性、管理便利等优势。目前 API 网关的相关工具链还不成熟,尽管这是可行的但也要够大胆才能用。工具链前面关于工具链还不成熟的说法是指大体上 FaaS 无服务器架构平台的情况,也有例外,Auth0 Webtask 就很重视改善开发者体验,Tomasz Janczuk 在最近一届的 Serverless Conf 上做了精彩的展示。无服务器应用的监控和调试还是有点棘手,我们会在本文未来的更新中进一步探讨这方面。开源无服务器 FaaS 的一个主要好处就是只需要近乎透明的运行时启动调度,所以这个领域不像 Docker 或者容器领域那么依赖开源实现。未来肯定会有一些流行的 FaaS / API 网关平台实现可以跑在私有服务器或者开发者工作站上,IBM 的 OpenWhisk 就是一个这样的实现,不知道它是否能成为流行选择,接下来的时间里肯定会有更多竞争者出现。除了运行时的平台实现,还是有不少开源工具用以辅助开发和部署的,例如 Serverless Framework 在 API 网关 + Lambda 的易用性上就比它的原创者 AWS 要好很多,这是一个 JS 为主的项目,如果你在写一个 JS 网关应用一定要去了解下。再如 Apex——“轻松创建、部署及管理 AWS Lambda 函数”。Apex 有意思的一点是它允许你用 AWS 平台并不直接支持的语言来实现 Lambda 函数,比如 Go。什么不是 Serverless在前文中我定义了 “Serverless” 是两个概念的组合:“Backend as a Service” 和 “Function as a Service”,并且对后者的特性做了详细解释。在我们开始探讨它的好处和弊端之前,我想再花点儿时间在它的定义上,或者说:区分开那些容易和 Serverless 混淆的概念。我看到一些人(包括我自己最近)对此都有困惑,我想值得对此做个澄清。对比 PaaS既然 Serverless FaaS 这么像 12-Factor 应用,那不就是另一种形式的 Platform as a Service 么?就像 Heroku?对此借用 Adrian Cockcroft 一句非常简明的话:如果你的 PaaS 能在 20ms 内启动一个只运行半秒钟的实例,它就叫 Serverless。— Adrian Cockcroft换句话说,大部分 PaaS 应用不会为了每个请求都启动并结束整个应用,而 FaaS 就是这么做的。好吧,然而假设我是个娴熟的 12-Factor 应用开发者,写代码的方式还是没有区别对么?没错,但是你如何运维是有很大不同的。鉴于我们都是 DevOps 工程师我们会在开发阶段就充分考虑运维,对吧?FaaS 和 PaaS 在运维方面的关键区别是伸缩性(Scaling)。对于大多数 PaaS 平台而言你需要考虑如何伸缩,例如在 Heroku 上你要用到多少 Dyno 实例?对于 FaaS 应用这一步骤是完全透明的。即便你将 PaaS 配置为自动伸缩,也无法精细到单个请求级别,除非你有一个非常明确稳定的流量曲线可以针对性地配置。所以 FaaS 应用在成本方面要高效得多。既然如此,何必还用 PaaS?有很多原因,最主要的因素应该是工具链成熟度。另外像Cloud Foundry 能够给混合云和私有云的开发提供一致体验,在写就本文的时候 FaaS 还没有这么成熟的平台。对比容器使用 Serverless FaaS 的好处之一是避免在操作系统层面管理应用程序进程。有一些 PaaS 平台如 Heroku 也提供了这样的特性;另一种对进程的抽象是容器,这类技术的代表是 Docker。容器托管系统(Mesos、Kubernetes 等)把应用从系统级开发中抽象出来,这种做法日渐流行,甚至在此之上云服务商的容器平台(如 Amazon ECS、EKS、Google Cloud Engine)也像 Serverless FaaS 一样允许团队从管理主机中完全解放出来。在这股容器大潮中,FaaS 是否还有优势?概念上来说前面对 PaaS 的论断仍旧适用于容器。Serverless FaaS 的伸缩性是完全自动化、透明、良好组织的,并且自动进行资源监控和分配;而容器平台仍旧需要你对容量和集群进行管理。另外我还得说容器技术也处在不够成熟和稳定的阶段,尽管它越来越接近了。当然这不是说 Serverless 就成熟了,但你终究需要在两个都属前沿的技术方向中做出选择。还有个值得一提的是不少容器平台支持了自动伸缩的容器集群,Kubernetes 有内建的 Horizontal Pod Autoscaling 功能,AWS Fargate 则承诺会有“Serverless 容器”。总的来说 Serverless FaaS 和托管容器在管理和伸缩性方面的差别已经不大,在它们之间的取舍更多看风格取向和应用的类型。例如事件驱动的应用组件更适合用 FaaS 实现,而同步请求驱动的应用组件更适合用容器实现。我预计很快就会有不少团队和应用同时采用这两种架构模式,期待看它们会擦出怎样的火花。对比 NoOpsServerless 并非“零运维”——尽管它可能是“无系统管理员”,也要看你在这个 Serverless 的兔子洞里走多深。“运维”的意义远不止系统管理,它还包括并不限于监控、部署、安全、网络、支持、生产环境调试以及系统伸缩。这些事务同样存在于 Serverless 应用中,你仍旧需要相应的方法处理它们。某些情况下 Serverless 的运维会更难一些,毕竟它还是个崭新的技术。系统管理的工作仍然要做,你只是把它外包给了 Serverless 环境。这既不能说坏也不能说好——我们外包了大量的内容,是好是坏要看具体情况。不论怎样,某些时候这层抽象也会发生问题,就会需要一个来自某个地方的人类系统管理员来支持你的工作了。Charity Majors 在第一届 Serverless 大会上就这个主题做了个非常不错的演讲,也可以看看她相关的两篇文章:WTF is operations? 和 Operational Best Practices)。对比存储过程即服务还有一种说法把 Serverless FaaS 看做“存储过程即服务(Stored Procedures as a Service)”,我想原因是很多 FaaS 函数示范都用数据库访问作为例子。如果这就是它的主要用途,我想这个名字也不坏,但终究这只是 FaaS 的一种用例而已,这样去考虑 FaaS 局限了它的能力。我好奇 Serverless 会不会最终变成类似存储过程那样的东西,开始是个好主意,然后迅速演变成大规模技术债务。— Camille Fournier但我们仍然值得考虑 FaaS 是否会导致跟存储过程类似的问题,包括 Camille 提到的技术债。有很多存储过程给我们的教训可以放在 FaaS 场景下重新审视,存储过程的问题在于:通常依赖于服务商指定的语言,或者至少是指定的语言框架/扩展因为必须在数据库环境中执行所以很难测试难以进行版本控制,或者作为应用包进行管理尽管不是所有存储过程的实现都有这些问题,但它们都是常会碰到的。我们看看是否适用于 FaaS:第一条就目前看来显然不是 FaaS 的烦恼,直接排除。第二条,因为 FaaS 函数都是纯粹的代码,所以应该和其他任何代码一样容易测试。整合测试是另一个问题,我们稍后展开细说。第三条,既然 FaaS 函数都是纯粹的代码,版本控制自然不成问题;最近大家开始关心的应用打包,相关工具链也在日趋成熟,比如 Amazon 的 Serverless Application Model(SAM)和前面提到的其他 Serverless 框架都提供了类似的功能。2018 年初 Amazon 还开放了 Serverless Application Repository(SAR)服务,方便组织分发应用程序和组件,也是基于 AWS Serverless 服务构建的。关于 SAR 可以看看我的另一篇文章:Examining the AWS Serverless Application Repository。本文翻译的实时更新:https://amio.github.io/server… ...

November 13, 2018 · 3 min · jiezi

一文拆解Faas的真实案例

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~本文来自腾讯云技术沙龙,本次沙龙主题为Serverless架构开发与SCF部署实践 刘敏洁:具有多年云计算行业经验,曾任职于华为、UCloud等企业担任产品开发、产品经理。目前负责腾讯云API生态的推广,帮助开发者进行API网关与无服务器函数、容器、微服务等产品的结合使用,提供完整解决方案。这次我们主要介绍面向于API网关和SCF深度结合应用,API网关与SCF结合可以形成比较完整的Serverless方案。今天的内容分为四部分:第一,API网关这个产品本身的简单介绍和一些能力。第二,API网关和SCF也就是是我们无服务器函数结合使用的时候提供了哪些能力跟它结合方便大家使用。第三,在比较常用的场景中我们整体的使用架构以及现在客户真正使用的案例。最后是大家关心的费用问题。我们做API网关这个产品的初衷不单单是一定说跟SCF强绑定的,是在用户使用中,遇到了很多问题。那么最开始我们为什么会做这个产品?在场大家多数都是做开发的应该很清楚了,比如前端的调用方式越来越多了,后端的部署方式越来越多了,可以用自己的物理机,可以买一个云主机,可以搞一个容器,可以像使用现在更新的微服务,无服务器计算。那么在这种复杂的情况下前端和后端的耦合就会造成业务上在扩容,在做一些新的业务增加的时候变得麻烦。那么此时,解耦就变得异常重要。市面上也有一些API网关这样的开源产品,但是运维的成本,费用问题也会分摊到每个开发同学身上,既然如此我们就在想何不做一个以服务的形式提供API网关能力的产品给客户呢。所以有了今天给大家介绍的API网关这样一款产品。API网关在一般场景下怎么使用的?有一个很简单的电商例子,多数情况下客户后端有很多的业务模块,有商品、用户这些常用的业务模块。如果在以前,可能是前端的APP,小程序,直接调用这些模块,后端也是以API形式提供给前端调用的。但是前端需要理解每个模块的API。现在我们提供API网关服务,客户在使用API网关后,我们建议客户把他们的每个业务模块跟我们API网关进行对接。由API网关统一输出一个API提供给前端调用。包括前面说的小程序,外部API,都是这样的一种可以在前端调用的方式。其实用一句话来总结一下,我们API网关这个服务是什么呢?就是API的一个托管服务,可以对多种后端能力进行统一的管理,输出无状态服务的API给到前端调用。用户可以在API网关上创建API,发布API,上线、下线等。包括建成限流,监控这样的一些能力,这些能力在解耦过程中都是非常需要的。这里总结了几个比较大的能力点:首先,统一鉴权认证,这是非常重要安全防护的能力。API转化和隐藏,像参数,位置,名称都可以做转化和映射,经过映射后真正的调用者不一定拿到这些后端的真实数据。流控和配额也是常见的能力,通常后端业务资源其实是有限的,所以前端需要将API的QPS和配额做限制。另外还有输出API能力,现在腾讯云提供了API市场,如果用户后台有一些业务,有一些能力,有一些数据,想通过API提供出去给第三方伙伴直接进行售卖,都可以通过这个网关输出到API网关进行直接售卖。自动化文档和SDK这个能力呢,其实是针对方便调用者进行调用的,如果我们有了业务后再手写文档,这个工作量也很大,所以API网关可以自动帮助客户生成文档,还有SDK供客户调用。强负载能力,腾讯云API网关依赖于腾讯大的负载平台,可以应对大的突发请求不惧怕大的负载,性能方面是很有保证的。最后,API网关可以对API进行安全防护,对调用API原IP做白名单。这里其实是比较完整的流转方式。API网关分两种角色:一个是发布API的人,一个是调用API的人,他们可能是同一些人,也可能是分别两拨人。发布者先把API发布到API网关中,参数,认证,鉴权,映射等等都需要进行配置,发布者配置后可以直接在API网关控制台上进行调试,在控制台上看看这个通不通,后台响应正不正常,Ok不Ok。如果调试都成功了进行API的发布。发布后就可以把API提供给调用者了。那么API网关怎么提供API给调用者呢?我们的服务其实是以域名的形式提供给调用者的。我们会提供默认的二级域名。当然客户有自己的域名,也可以把这个域名绑到我们二级域名上。另外API网关可以生成文档SDK,提供给调用者。调用者直接使用文档、SDK可以方便的调用。调用后,前端请求到API网关后,API网关会根据之前发布的配置做一些认证,鉴权这样一些基础的校验。到后端我们会做参数的映射,最终把这个请求发到后端业务。其实后端可以对接很多云服务,像SCF,像其他云服务统统都是可以对接的。当然今天主角是无服务器函数,所以我们主要讲一下对接到SCF。对接后它会拉起它的服务响应,根据响应看是不是做一些映射,最后把结果丢会调用者。在这个过程中发布者可以看到监控的信息是怎样,也可以查询到调用。如果调用失败,或者有什么错误,是前端的还是后端的,整个日志都是可以查询到的。这是一个比较完整的流程。我们现在可以看一下API怎么跟SCF结合使用。其实很简单,前面是API网关做一个触发器。用触发器的形式来触发SCF后端的函数。然后SCF做一些计算处理,结束后它可能落到后边的像数据库这些服务,在图中的没有画出来。这种方式现在APP,小程序都是很常用的,包括给第三方合作伙伴,就是它们直接提供API给第三方合作伙伴,不走任何的平台,这种都是非常常用的一种方式。安全与限流,刚刚在我们整个功能里其实有做了一个简单的说明。这里分几块说:第一,我们提供认证能力。认证的能力像密钥对是现在常用的认证方式,我们在网关上生成密钥对,把这个提供给调用者。这个密钥对常用是服务器端对服务器端。也有像用OAuth这种单点登录,客户有自己认证服务器的,我们也是支持的,可以去用API网关对接认证服务器。认证服务器去对调用做认证鉴权,然后我们在做一些校验。这是对整个认证管理做一个安全性的保障。其实还有刚才说的源IP黑白名单。这个常见于大家内部用的,比如我是一个大的公司,内部几个部门之间用。另外限流的部分,当后端业务能承载的QPS有限的时候,在API这边做一个限流控制,如果超过这个QPS,就把这个调用丢掉,后端不会过载。CORS,现在跨域的调用非常多的,比如电商,还有一些WEB页,像CSS、JS静态调用,访问时需要浏览器跨域调用。当请求是跨域请求时,API网关会根据发布者的配置做一些处理,比如配置支持跨域,API网关会把这个CORS头去。直接响应回来后我们再把CORS头放回响应中。这完成的是跨域调用。这样的话其实对SCF开发者会比较方便使用,就不用再操心跨域的问题。响应集成这种也是常见的使用,用户开发小程序时的场景也是响应集成可能比较常用到。比如在对接前面的接口时,需要把SCF抽取成真正的HTTP格式请求返回给前端。API网关与SCF之间同样为HTTP请求,SCF函数返回的响应在响应透传模式时,会被全部放进API网关的响应body中,返回给调用者。这样的话可以直接对接很多已经有一些规范,已经有一些接口的,像小程序这种,会不适用这种方式。那么就需要API网关把SCF的响应抽取为一个标准HTTP的respond返回个标准接口。Websocket能力算是在函数计算里的一个难点,因为本身函数不是常驻的,比如说这个函数跑一跑,在没有触发的时候,可能有一个时间段过去后,目前的资源就释放掉了,下次再触发的时候再拉起来,这很难跟前端保持长连接。那我们怎么帮SCF处理长连接问题的呢?API网关会帮每一个前端的调用者生成一个唯一的ID,这个ID就注册到后面客户的业务函数里。当客户业务函数需要推送的时候,他只要带到这个唯一ID给API网关,API网关就会将这个唯一ID的消息丢给前端,这样我们唯一ID和前面的连接保持了长连接,也保证了后端推送的正确性。举个例子,一个聊天室,有三个人聊天,范冰冰,李晨和黄晓明。他们三个都有唯一ID。黄晓明发出来一句话,后面的函数收到这句话,并且要把他说的话推送给范冰冰和李晨,那么通过唯一ID,可以识别到三个人,后端业务将黄晓明ID的聊天语句推送到API网关,告诉API网关要将此信息推送给范冰冰和李晨ID的前端,API网关收到信息后,则将此信息推送到与范冰冰李晨的客户端保持的长连接中,他们就看到了这条信息。这就是处理Websocket长连接的方式。开放到API市场上,刚才我们也简单说了一下,其实很多能力,我们自己一些能力和数据想直接开放出去给别人,但是并不想做一个页面,计费流程,那么可以放到API市场来进行售卖。其实后端业务放到SCF上是提供服务的一种方式,这样有些用户业务是放在API市场上来进行售卖的。这是把我们技术能力变现的一种方式。文档与SDK刚才也说了很多,这里再来介绍一下。如果用户配了10个API,API网关会帮用户生成这10个API的文档和SDK。swagger文档有点像代码式的文档另外还有普通文字描述的API文档,这两种我们都能生成。生成后可以直接下载下来提供给别人。SDK中有鉴权相关的代码,调用者使用时把自己的参数填进去,对调用者来说更方便。高并发,这里我们还是想强调一下,API网关可以扛住非常非常大的并发请求。当用户请求的并发量极大时,并且有大量HTTPS时,大量请求十分消耗CPU。ABI网关的高性能,及时HTTPS请求的异步处理,可以应对高并发场景,保证服务可用。场景方面,刚才说的是一些具体功能,我们能帮SCF做哪些具体的能力。在整体结构的使用场景这里做一些介绍,这里是小程序公众号,电商这种业务场景现在使用的一些客户的架构,客户的很多业务模块放到SCF上面,然后用API网关作为API服务提供出去。前端无论是小程序还是APP只要有鉴权,有密钥对都可以来进行调用。后端根据自己的业务去跟MySQL等能力来进行对接。刚刚这种方式,像乐凯撒是一个很典型的例子。他们把他们的菜单系统,还有微信支付都放在SCF上面。前端会对接一些固有的HTTP接口,所以用了我们的响应集成的能力,就是API网关帮他抽取成一个标准的HTTP响应返回给前面的调用者。另外因为有很多图片静态资源,他们也使用了跨域能力,这样后端上线的时候非常快。乐凯撒现在有一个小程序用户可以直接在上面下单买披萨,这个小程序中的很多能力是使用上述架构完成的。他们的ERP也有一些后台的系统,也是直接在SCF上进行后台计算,用API网关直接出接口。其实很多能力可以复用,那么API本身就可以进行复用。这样的开发流程,会让整个上线过程非常的迅速。现在用的多的还有AI推理和翻译。用户将自身的计算模型,翻译模型等放在SCF上,每次通过API网关触发来触发计算。API网关将请求带来的数据给到后端,并对每个请求做鉴权认证或ACL管理保障使用的安全性。比较典型的就是搜狗,搜狗在这里其实有一个翻译推理的模型,放在SCF上, SCF跑在GPU上,然后通过API网关做触发。这里用API网关主要是想做前后的解耦。因为搜狗的业务本身解耦是C++写的,所有的请求都是用http的方式传递,请求端和后台解耦合后,很多后端业务不再需要用python重写。荔枝微课是一个在线教育课程。它的情况是,后端SCF跑了一个模型计算。每次当客户在他的页面上搜某个课程。它的前端会把这个课程,用户感兴趣的课程信息,包括客户的ID,之前的一些信息带到后端带给SCF。SCF模型拿到了客户信息,它本身也会有一些自己的原有的信息,这些信息结合起来,再根据其算法进行计算。最后得出的结论,这个客户喜欢某些课程,再把这个课程推送到前端来,最终展示在WEB页上。在这个中间,其实API网关和SCF解耦的时候,对API网关的模型调用,需要有安全保证的,就是有不同IP的时候有源IP调用,还有密钥对的鉴权对后端进行安全保障。另外如果说这个SCF或者调用有任何问题的话,监控报警也是可以快速让我感知到这个模型的状态。最后看一下费用,我们费用也是有很大力度减免的,每月有一百万次的免费调用。网络费用跟公网的的价格是一样的,调用次数0.04元/万次。目前没有收费,预计到年底收费。但是整个资源费用是非常便宜的,所以如果有想试用的同学不用很犹豫。 Q:主要想请问涉及到有时候有自己的线上环境和我们的测试环境,我想知道我们现在如果使用你们的API网关还有SCF,我们怎么去部署这样两套环境?怎么样去完成像我们现在使用的这些持续集成,怎么结合到我现有的产品?因为我目前看到的展示都是基于控制台,没有看到说基于CLI的操作,所以想了解一下。A:其实我们API网关有环境管理和版本管理。版本管理也分了环境,测试环境这些标准环境。后续还会开放这些环境让用户自定义这些环境。CLI部分我理解需要在公台操作,还是命令行操作,本身跟我提不提供环境管理,版本能力应该是两个事情。所以CLI后续会提供。但是本身需要的开发和测试环境我们已经分环境提供。Q:新的代码更新后要上线到SCF上怎么部署?A:后面我们会做一个工具,在这个工具上,比如CLI,可以一键上传,并且配一些API网关。目前这个都在开发中。Q:怎么样买服务器便宜,怎么样买按调用次数的偏移?A:这个还是需要你本身业务来计算一下。比如说我这个业务就是一个触发型的业务,我如果用一个CPM或者物理机部署的话,如果常驻型的话需要占到多少钱,这个钱其实是固定的,每个月需要多少钱。但是如果我知道这个业务是触发型,假如每天就调用一万次,这个也是能算出来的钱。这个钱一比较就很简单就出来了。但是这个都得基于你本身业务的调用量和你本身业务后端消耗资源的情况来进行计算的。所以我没法儿给你一个直接的值。如果真的需要一个常驻的业务,一天二十四小时一直在跑的话,其实这个也是要看,这二十四小时在跑的,我对我本身的服务器我的消耗情况,比如说我买完了一台服务器,市面上的服务器可能就那么多,或者说CPM就那么多,即便买了最小的4核服务器都没跑满,如果计算很轻量没法儿跑满的话,用SCF也会很划算。但是需要大量的,可能用本身的传统的方式会比较简单。Q:在调用的稳定性,延时方面Serverless会有优势吗?A:其实调用的稳定性是我们服务稳定性的保障,这个不用担心,因为我们有承诺。至于延时,是有很多因素影响的,如果你是公网调用,这基于网络的一些情况。如果说API网关到SCF结合的话,本身API网关和SCF可以走内网和公网。API网关本身的延时是在毫秒级别,这个我们测试过的,还是很小的。如果部署一个服务器或者资源,你到那个网络之间的延时,你自己本身原来延时是多少还是要算一下。我可以告诉你我们的延时本身是多少,在可测的环境下我们的延时是多少。但是到你们具体的网络环境下还是要具体测量的。本文PPT附件请点击原文下载。问答Serverless:如何删除一个函数? 相关阅读多个场景中的AI落地实践低于0.01%的极致Crash率是怎么做到的? 【每日课程推荐】机器学习实战!快速入门在线广告业务及CTR相应知识

September 7, 2018 · 1 min · jiezi