译者 | 胥磊
审校 | 孙淑娟
在本系列的第一篇文章中,我们探讨了为什么坚信Serverless是云计算的未来,期间我们研究了云计算的演变,也列举了当前已经转向Serverless模式的一些用例。在本文中,我们将进一步阐述如何实现Serverless以及实现过程中将会遇到的挑战。最后将通过论点总结和愿景展望来结束这个系列。

转向一个更纯粹的Serverless的世界将能解决现代工作负载运行时遇到的许多问题,但同时也存在很多挑战。本文中,我们将这些挑战分为四大类:云优化、服务设计、功能和工作流以及安全问题,分别展开来进行探讨。在每个大类中我们都列出了重要的,有待彻底解决的具体问题。虽然不是很全面,但我们坚信这些将成为Serverless社区规划线路的基石。
类别 | 挑战 | 应对挑战需改进的措施 |
云优化 | 减少分配和释放计算资源的开销 | 需要改进云系统组件的设计(主要Kubernates) |
减少服务延迟 | 需要改进云系统组件的设计(主要Kubernates) | |
支持暂停工作节点 | 需要对使用的资源进行碎片整理(需要KNative和Kubernetes支持) | |
服务设计 | 外部化服务流事件 | 需要服务设计支持事件驱动 |
处理延时问题 | 需要服务设计时要考虑延时 | |
对事件风暴,概率性的事件降低以及事件不可用的处理 | 需要云系统(Knative)设计和相关服务设计时考虑支持 | |
功能和工作流 | 服务标准化 | 需要社区能满足行业标准 |
不同服务的工作流的通用描述 | 需要完整的工作流语言 | |
安全问题 | 更多的权限从用户本地转移到云端自动处理 | 云计算需要保护可能存在漏洞的服务方面发挥更积极的作用 |
工作负载更细粒度的分类扩大了被攻击面 | 增加自动化和版本控制,以减少配置任意性,并支持频繁的服务更新 | |
网络边界的消失 | 增加安全新闻的监测和控制(Knative,Kubernetes) |
Serverless适合为服务需求分配计算资源,它在服务需求增长时分配新的计算资源,而在需求减少时释放相关计算资源。这里的分配和释放计算资源的开销问题可能是Serverless应用部署后出现的最重要的问题之一。
Serverless服务(无论函数,容器或者是工作流运行的容器组)都会产生计算资源的缩减和回升的成本,而且这种成本的量可能相当可观,因为其贯彻了Serverless服务的生命周期的各个环节。包括Kubernetes在内的大多数云技术在设计时都考虑了服务资源的预配置。在Serverless模式下,就必须要考虑通过降低运行中实例的变化而产生的开销来优化更多的动态用例。例如,Kubernetes添加一个Pod副本就必须进行优化,通过最大限度的减少开销,以便于每次服务需求变化时成本和能源消耗降到最低。
另一方面需要注意的是,应对需求增长,在增加计算资源过程中所带来的服务延迟。当你等待额外的资源被分配时,期间就会导致服务延迟的增加。极端情况下,当一个请求到达一个还没有分配资源的服务时,冷启动的时间会导致该请求受到非常显著的影响。正如在Knative减少冷启动时间所讨论的那样,最坏的情况下服务启动时间是以秒为单位,而请求的响应时间通常则只有几十毫秒。当你创建由多个独立扩展组成的Serverless解决方案时,冷启动带来的影响是非常显著的,必须考虑到这一点。进一步改善这个问题就需要对云技术进行更多优化。
最后需要对KUbernetes和Knative进行优化,以充分发掘其解决能源和资金节约的潜力。Pod分配和集群控制应发展到支持动态调整(碎片整理)到其他工作节点的子集,这样空闲的节点就可以暂停,当然当集群资源总体需求增加时还可以恢复。
当你创建Serverless应用或解决方案时,主要挑战之一就是要以事件驱动的思维模式来设计应用和服务,也就是要去了解应用和整体方案各部分运行的事件。这些事件来自你对应用领域的业务理解,必须被明确的提取出来。例如在一个业务流程的应用中,如:假期预定系统,就有明确的事件来驱动整个应用的使用。当客户计划一个假期时,他们必须依次选择和预定一系列的选项,如地点、航班、酒店、租车、餐饮以及其他活动。整个的过程可以被分解为服务以及它们之间流转的事件,企业将其应用设计成微服务,这种分解和设计也是众所周知的。
Serverless的事件驱动架构只是简单的对不同的服务增加了事件(内部或外部)触发,如果它们没有处理任何请求时,可以缩减到零。为了充分发挥这种架构的优势,必须将驱动服务的事件外部化,这样就可以用这些事件来触发Serverless组件网中的工作流。由于服务都是可以动态扩展的,就出现了之前提到的一个问题就是需要考虑冷启动的潜在影响,同时还需要有一个显示良好且响应快速的用户界面。
事件驱动架构也有自己必须要解决的一系列挑战,大部分可以通过选择正确的事件代理、触发器和事件模型来解决。而你应用程序的部分也需要注意一些陷阱,特别是事件风暴或一段时间后可能发生事件减少或不起作用的问题。以上所有这些就是我们所说的Serverless设计。
AWS在2014年推出其Lambda服务时,介绍的第一个模型就是一个纯粹的函数式编程模型。服务是以定义在不同语言和库中的函数的形式执行。后来Knative提出了一个更通用的模型:以容器为中心,像Lambda函数一样,执行是基于事件的触发,并随着服务的需求(请求)的变化增减资源规模。随后,Knative适时推出了自己的函数式编程模型:Knative函数。
虽然不同的Serverless技术的共存对创新有很大帮助,但毕竟它们是不兼容的,因为不存在一个标准,而兼容性的挑战在网络边界得到了解决。首先,容器镜像的格式和执行正在由Kubernetes社区定义。最重要的是很多Serverless平台的事件模型是基于云事件标准,这是个非常重要的标准。它允许工作负载跨云合作,协作和执行。Kubernetes提供了通用的执行平台,以及我们需要的该平台上Serverless的通用定义。
最后一个挑战是Serverless服务之间协调流转的通用描述。创建一个简单的Serverless解决方案不仅需要触发器、事件源和不同服务的事件汇聚,还需要不同服务之间的协调。在各种流程语言中存在部分解决方案,那就是管道语言,但它不是为任意的带有同步点的复杂图设计的,更需要一种完整的工作流语言。这种语言可能是Tekton演变出来的,或者至少是其一个超集。
伴随每一项新技术的出现,新的网络安全挑战往往也随之而来。而Serverless技术的出现改变了这种格局,因为更多的控制权从用户端转移到云端自动化,特别是对在何处使用多少计算资源来满足需求的控制。由此伴随网络边界逐渐消失,许多相关的安全控制也随之消失。此外,伴随Serverless带来的低成本和简化操作,许多的工作负载将被划分为更细的自助服务,而工作负载的片段越来越多,攻击者也会看到更大的攻击面。
Knative提供了协助服务修正的基本功能,支持在服务修正过程中进行流量切分,从而使服务在修正版本的迭代期间能平滑、无风险的过度。支持更高频率的更新,以降低不断变化的威胁和新发现的漏洞所带来的风险。
Knative自动化部署确保服务所需的所有Kubernetes资源都出自单一的服务资源。违规者或内部人员对任何资源的手动修改,无论有意还是无意都会被Knative自动化覆盖,避免配置任意修改。
Knative使用Kubernetes来协助管理Knative的底层组件,但并不支持对Serverless的基础设置进行手动更改。
Knative社区正在引入新的技术来监控已部署服务的行为以及发送到这些服务的事件的行为。安全卫士是一种为每个服务量身定制的、运行时的安全保障,用于防护脆弱的服务免受0-day或已知漏洞的威胁。该技术还为你提供机制以应对服务被利用的情况。
随着云计算的不断发展,它已成为全球能耗的一个重要角色,据国际能源署的估计其已经占了2021年全球能源消耗的1-1.5%和二氧化碳排放量的1%!Kubernetes规范了工作负载的部署和管理方式。而Knative凭借Serverless和高效性向前更进一步,它有助于实现更环保的云计算,并为云服务商和云用户节省大量成本,这种Serverless模式适用于所有的工作负载。更高的效率不仅仅是对单个工作负载来说的,还包括底层云资源和每个工作负载的执行所消耗的能源。
除了效率之外,Serverless还为云用户带来别的额外好处,包括简单化、自动化、版本修正管理和网络安全的改善。然而这些也同样存在挑战,Kubernetes需要更进一步优化基于实际负载自动扩展服务的动态特性。为了使Serverless更加通用,并涵盖更多的用例场景,还有许多工作需要做。同样为了使用Serverless模式,用户也必须改进他们的工作负载和部署的策略,当然这些都需要时间。
随着我们逐渐转向Serverless模式,适用的新的工作负载和用例场景也是我们需要考虑的。人工智能,数据和机器学习社区在认知这种按需分配计算资源模式的价值方面取得先机,Kubeflow和Tekon都是以Serverless模式设计和执行数据密集型AI管道以及工作负载的很好的例子。其他未来可用的工作负载和用例场景还包括量子Serverless,通过它可以在量子计算机上按需使用或执行量子算法。
Serverless模式代表了成本节约和分配资源的经济性,应用是为这而设计的,而平台对于运行Serverless解决方案也是高效和经济的,所以对各方都是有意义的。另外作为额外的奖励,对环境也是有好处的。
感谢Paul Schweigert和Lionel Villard的反馈和意见。此外还要感谢整个Knative社区,感谢他们为创建Kubernetes的Serverless平台所做的贡献和努力,在不到两年的时间里,社区已经发布了十几个版本,改进了各个方面并保持与Kubernetes的兼容,且允许扩展和实验各种创新。
胥磊,51CTO社区编辑,某头部电商技术副总监,关注Java后端开发,技术管理,架构优化,分布式开发等领域。
原文标题:How do we make the future serverless?,作者:Michael Maximilien, David Hadas, Angelo Danducci II, Simon Moser
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg
通常,数组被实现为内存块,集合被实现为HashMap,有序集合被实现为跳跃列表。在Ruby中也是如此吗?我正在尝试从性能和内存占用方面评估Ruby中不同容器的使用情况 最佳答案 数组是Ruby核心库的一部分。每个Ruby实现都有自己的数组实现。Ruby语言规范只规定了Ruby数组的行为,并没有规定任何特定的实现策略。它甚至没有指定任何会强制或至少建议特定实现策略的性能约束。然而,大多数Rubyist对数组的性能特征有一些期望,这会迫使不符合它们的实现变得默默无闻,因为实际上没有人会使用它:插入、前置或追加以及删除元素的最坏情况步骤复
在ruby中,你可以这样做:classThingpublicdeff1puts"f1"endprivatedeff2puts"f2"endpublicdeff3puts"f3"endprivatedeff4puts"f4"endend现在f1和f3是公共(public)的,f2和f4是私有(private)的。内部发生了什么,允许您调用一个类方法,然后更改方法定义?我怎样才能实现相同的功能(表面上是创建我自己的java之类的注释)例如...classThingfundeff1puts"hey"endnotfundeff2puts"hey"endendfun和notfun将更改以下函数定
我目前有一个reddit克隆类型的网站。我正在尝试根据我的用户之前喜欢的帖子推荐帖子。看起来K最近邻或k均值是执行此操作的最佳方法。我似乎无法理解如何实际实现它。我看过一些数学公式(例如k表示维基百科页面),但它们对我来说并没有真正意义。有人可以推荐一些伪代码,或者可以查看的地方,以便我更好地了解如何执行此操作吗? 最佳答案 K最近邻(又名KNN)是一种分类算法。基本上,您采用包含N个项目的训练组并对它们进行分类。如何对它们进行分类完全取决于您的数据,以及您认为该数据的重要分类特征是什么。在您的示例中,这可能是帖子类别、谁发布了该项
我查看了Stripedocumentationonerrors,但我仍然无法正确处理/重定向这些错误。基本上无论发生什么,我都希望他们返回到edit操作(通过edit_profile_path)并向他们显示一条消息(无论成功与否)。我在edit操作上有一个表单,它可以POST到update操作。使用有效的信用卡可以正常工作(费用在Stripe仪表板中)。我正在使用Stripe.js。classExtrasController5000,#amountincents:currency=>"usd",:card=>token,:description=>current_user.email)
虽然1.8.7的构建我似乎有一个向后移植的Shellwords::shellescape版本,但我知道该方法是1.9的一个特性,在1.8的早期版本中绝对不支持.有谁知道我在哪里可以找到(以Gem形式或仅作为片段)针对Ruby转义的Bourne-shell命令的强大独立实现? 最佳答案 您也可以从shellwords.rb中复制您想要的内容。在Ruby的颠覆存储库的主干中(即GPLv2'd):defshellescape(str)#Anemptyargumentwillbeskipped,soreturnemptyquotes.ret