1 - Serverless介绍

serverless介绍

1.1 - CNCF Serverless白皮书

CNCF Serverless白皮书

备注:内容翻译自 https://github.com/cncf/wg-serverless/tree/master/whitepapers/serverless-overview

本文描述了新型云原生计算模型,该模型由新兴的“serverless”架构及其支持平台实现。它定义了serverless计算的内容,重点介绍了serverless计算的用例和成功示例,并展示了serverless计算如何与其他云应用程序开发模型(如Infrastructure-as-a-Service (IaaS), Platform-as-a-Service (PaaS),容器编排或Container-as-a-Service(CaaS)。

本文包含对通用serverless平台机制的逻辑描述,还有和这些平台相关的编程模型和消息格式,但它没有规定标准。它介绍了几种行业serverless平台及其功能,但不推荐特定实现。

最后,还有关于CNCF如何推进云原生计算的serverless计算的一系列建议。

工作组主席/TOC发起人: Ken Owens (Mastercard)

作者 (按姓氏字母顺序排列):

Sarah Allen (Google), Chris Aniszczyk (CNCF), Chad Arimura (Oracle), Ben Browning (Red Hat), Lee Calcote (SolarWinds), Amir Chaudhry (Docker), Doug Davis (IBM), Louis Fourie (Huawei), Antonio Gulli (Google), Yaron Haviv (iguazio), Daniel Krook (IBM), Orit Nissan-Messing (iguazio), Chris Munns (AWS), Ken Owens (Mastercard), Mark Peek (VMWare), Cathy Zhang (Huawei)

其他贡献者 (按姓氏字母顺序排列):

Kareem Amin (Clay Labs), Amir Chaudhry (Docker), Sarah Conway (Linux Foundation), Zach Corleissen (Linux Foundation), Alex Ellis (VMware), Brian Grant (Google), Lawrence Hecht (The New Stack), Lophy Liu, Diane Mueller (Red Hat), Bálint Pató, Peter Sbarski (A Cloud Guru), Peng Zhao (Hyper)

Serverless 计算

什么是serverless计算?

Serverless计算是指构建和运行不需要服务器管理的应用程序的概念。它描述了一种更细粒度的部署模型,应用程序捆绑一个或多个function,上载到平台,然后执行,缩放和计费,以响应当前所需的确切需求。

Serverless计算并不意味着我们不再使用服务器来托管和运行代码;这也不意味着不再需要运维工程师。相反,它指的是serverless计算的消费者不再需要花费时间和资源来进行服务器配置,维护,更新,扩展和容量规划。相反,所有这些任务和功能都由serverless平台处理,并完全从开发人员和IT/运维团队中抽象出来。因此,开发人员专注于编写应用程序的业务逻辑。运维工程师能够将重点更多的放到关键业务任务上。

Serverless有两个主要角色:

  • Developer/开发人员:为serverless平台编写代码并从中获益,serverless平台提供了这样的视角:没有服务器,而代码始终在运行。
  • Provider/供应商:为外部或内部客户部署serverless平台。

运行serverless平台仍然需要服务器。供应商需要管理服务器(或虚拟机和容器)。即使在空闲时,供应商也会有一些运行平台的成本。自托管系统仍然可以被视为serverless:通常一个团队充当供应商,另一个团队充当开发人员

Serverless计算平台可以提供以下中的一个或两个:

  1. Functions-as-a-Service (FaaS),通常提供事件驱动计算。开发人员使用由事件或HTTP请求触发的function来运行和管理应用程序代码。 开发人员将代码的小型单元部署到FaaS,这些代码根据需要作为离散动作执行,无需管理服务器或任何其他底层基础设施即可进行扩展。
  2. Backend-as-a-Service (BaaS),它是基于API的第三方服务,可替代应用程序中的核心功能子集。因为这些API是作为可以自动扩展和透明操作的服务而提供的,所以对于开发人员表现为是serverless。

Serverless产品或平台为开发人员带来以下好处:

  1. 零服务器运维:serverless通过消除维护服务器资源所涉及的开销,显着改变了运行软件应用程序的成本模型。

    • 无需配置,更新和管理服务器基础设施。管理服务器,虚拟机和容器对于公司而言是一项重大费用,其中包括人员,工具,培训和时间。Serverless大大减少了这种费用。

    • 灵活的可扩展性:serverless的FaaS或BaaS产品可以即时而精确地扩展,以处理每个单独的传入请求。对于开发人员来说,serverless平台没有“预先计划容量”的概念,也不需要配置“自动缩放”的触发器或规则。缩放可以在没有开发人员干预的情况下自动进行。完成请求处理后,serverless FaaS会自动收缩计算资源,因此不会有空闲容量。

  2. 闲置时无计算成本:从消费者的角度来看,serverless产品的最大好处之一是空闲容量不会产生任何成本。例如,serverless计算服务不对空闲虚拟机或容器收费; 换句话说,当代码没有运行或者没有进行有意义的工作时,不收费。 对于数据库,数据库引擎容量空闲等待请求时无需收费。当然,这不包括其他成本,例如有状态存储成本或添加的功能/功能/特性集。

Serverless技术简史

虽然按需或“花多少用多少”模式的概念可追溯到2006年和一个名为Zimki的平台,但serverless一词的第一次使用是2012年来自Iron.io的IronWorker产品 ,一个基于容器的分布式按需工作平台。

从那以后,公共云和私有云都出现了更多serverless实现。首先是BaaS产品,例如2011年的Parse和2012年的Firebase(分别由Facebook和谷歌收购)。2014年11月,AWS Lambda推出,2016年初在Bluemix上宣布了IBM OpenWhisk on Bluemix(现在是IBM Cloud Functions,其核心开源项目成为Apache OpenWhisk),Google Cloud FunctionsMicrosoft Azure Functions华为Function Stage于2017年推出。还有许多开源serverless框架。每个框架(公共和私有)都具有独特的语言运行时和服务集,用于处理事件和数据。

这只是几个例子; 有关更完整和最新的列表,请参阅 Serverless Landscape 文档。Detail View: Serverless Processing Model 部分包含有关整个FaaS模型的更多详细信息。

Serverless用例

虽然serverless计算广泛使用,但它仍然相对较新。通常,当工作负载为以下情况时,应将serverless方法视为首选:

  • 异步,并发,易于并行化为独立的工作单元
  • 不经常或有零星的需求,在扩展要求方面存在巨大的,不可预测的差异
  • 无状态,短暂的,对瞬间冷启动时间没有重大需求
  • 在业务需求变更方面具有高度动态性,需要加快开发人员的速度

例如,对于常见的基于HTTP的应用程序,在自动扩展和更细粒度的成本模型方面有明显的优势。也就是说,使用serverless平台可能会有一些权衡。 例如,如果function的实例数下降到零,则在一段不活动时间后function启动可能会导致性能下降。因此,选择是否采用serverless架构需要仔细查看计算模型的功能性和非功能性方面。

不适合IaaS,PaaS或CaaS解决方案的非HTTP中心和非弹性规模工作负载现在可以利用serverless架构的按需性质和高效成本模型。其中一些工作负载包括:

  • 执行逻辑以响应数据库更改(insert, update, trigger, delete)
  • 对IoT传感器输入消息(例如MQTT消息)执行分析
  • 流处理(分析或修改动态数据)
  • 管理单次提取,转换和加载的作业,这些作业需要在短时间内进行大量处理(ETL)
  • 通过聊天机器人界面提供认知计算(异步,但有关联)
  • 调度执行时间很短的任务,例如cron或批处理样式调用
  • 服务于机器学习和AI模型(检索一个或多个数据元素,如表格,NLP或图像,并与预先学习的数据模型匹配,以识别文本,面孔,异常等)
  • 持续集成pipeline,按需为构建作业提供资源,而不是保留构建从属主机池等待作业分派

本节介绍serverless架构优秀的现有和新兴工作负载和用例。它还包括从早期成功案例中提取的早期结果,模式和最佳实践的详细信息。

这些场景中的每一个都显示了serverless架构如何解决技术问题,即Iaas,PaaS或CaaS效率低下或无法实现。这些例子是:

  • 在没有按需模型的情况下,有效解决了一个全新的问题
  • 更有效地解决了传统的云问题(性能,成本)
  • 显示“大”的维度,无论是处理的数据大小还是处理的请求
  • 通过低错误率的自动缩放(向上和向下)来显示弹性
  • 以前所未有的速度(从天到小时)为市场带来了解决方案

多媒体处理

一个常见的用例,也是最早具体化的用例之一,是响应新文件上传执行一些转换过程的函数。 例如,如果将图像上载到诸如Amazon S3的对象存储服务,则该事件触发函数,用于创建图像的缩略图版本并将其存储回另一个对象存储桶或Database-as-a-Service。 这是一个相当原子化,可并行化的计算任务示例,该计算任务不经常运行并根据需求进行伸缩。

例子包括:

  • Santander 使用serverless function构建了一个概念验证,使用光学字符识别来处理移动支票存款。 这种类型的工作量变化很大,发薪日的处理需求 - 每两周一次 - 可能比支付期的大部分空闲时间大几倍。

  • 通过将 每个视频帧通过图像识别服务 来自动分类电影,以提取演员,情感和对象; 或处理灾区的无人机镜头以估计损坏的程度。

数据库更改或更改数据捕获(CDC)

在此场景中,当从数据库插入,修改或删除数据时调用function。在这种情况下,它的功能类似于传统的SQL触发器,几乎就像是与主同步流并行的副作用或动作。其结果是执行一个异步逻辑,可以修改同一个数据库中的某些内容(例如记录到审计表),或者依次调用外部服务(例如发送电子邮件)或更新其他数据库,例如 DB CDC(更改数据捕获)用例的情况。 由于业务需要和处理变更的服务分布的原因,这些用例的频率以及对原子性和一致性的需要可能不同。

例子包括:

  • 审核对数据库的更改,或确保它们满足特定质量或分析标准以进行可接受的更改。

  • 在输入数据时或之后不久自动将数据翻译为其他语言。

IoT/物联网传感器输入消息

随着连接到网络的自主设备的爆炸式增加,额外的流量体积庞大,并且使用比HTTP更轻量级的协议。 高效的云服务必须能够快速响应消息并扩展以响应其扩散或突然涌入的消息。Serverless功能可以有效地管理和过滤来自IoT设备的MQTT消息。 它们既可以弹性扩展,也可以屏蔽负载下游的其他服务。

例子包括:

  • GreenQ的卫生用例(垃圾互联网),根据垃圾箱的相对饱满度来优化卡车取件路线。

  • 在物联网设备(如AWS Greengrass)上使用serverless来收集本地传感器数据,对其进行规范化,与触发器进行比较,并将事件推送到聚合单元/云。

大规模流处理

另一种非事务性,非请求/响应类型的工作负载是在可能无限的消息流中处理数据。 函数可以连接到消息源,而消息必须从事件流中读取和处理。 鉴于高性能,高弹性和计算密集型处理工作负载,这对于serverless而言非常重要。 在许多情况下,流处理需要将数据与一组上下文对象(在NoSQL或in-mem DB中)进行比较,或者将数据从流聚合并存储到对象或数据库系统中。

例子包括:

聊天机器人

与人类交互不一定需要毫秒级别的响应时间,并且在许多方面,稍微延迟让回复人类的机器人对话感觉更自然。因此,等待从冷启动加载function的初始等待时间可能是可接受的。当添加到Facebook,WhatsApp或Slack等流行的社交网络时,机器人可能还需要具有极高的可扩展性,因此在PaaS或IaaS模型中预先设置一个永远在线的守护程序,以预测突然或高峰需求,可能不会有作为serverless方法的高效或成本效益。

例子包括:

  • 支持和销售机器人插入到大型社交媒体服务,如Facebook或其他高流量网站。

  • 消息应用程序Wuu使用Google Cloud Functions使用户能够创建和共享在数小时或数秒内消失的内容。

  • 另请参阅下面的HTTP REST API和Web应用程序。

批处理作业或计划任务

每天只需几分钟就能以异步方式进行强大的并行计算,IO或网络访问的作业非常适合serverless。作业可以在以弹性方式运行时有效地消费他们所需的资源,并且在不被使用的当天剩余时间内不会产生资源成本。

例子包括:

  • 计划任务可以是每晚运行的备份作业。
  • 并行发送许多电子邮件的作业会扩展function实例。

HTTP REST API和Web应用程序

传统的请求/响应工作负载仍然非常适合serverless,无论工作负载是静态网站还是使用JavaScript或Python等编程语言按需生成响应。即使它们可能会为第一个用户带来启动成本,但在其他计算模型中存在这种延迟的先例,例如将JavaServer Page初始编译为servlet,或者启动新的JVM来处理额外的负载。好处是单个REST调用(例如,微服务中的GET,POST,UPDATE和DELETE 4端点中的每一个)可以独立扩展并单独计费,即使它们共享公共数据后端。

例子包括:

移动后端

使用serverless进行移动后端任务也很有吸引力。它允许开发人员在BaaS API之上构建REST API后端工作负载,因此他们可以花时间优化移动应用程序,而不是扩展后端。 例子包括:优化视频游戏的图形,而不是在游戏成为病毒式打击时投资服务器; 或者对于需要快速迭代以发现产品/市场适合性,或者上市时间至关重要的消费者业务应用程序。另一个示例是批量通知用户或程序其他异步任务以获得离线优先体验。

例子包括:

  • 需要少量服务器端逻辑的移动应用程序; 开发人员可以将精力集中在原生代码开发上。
  • 使用已配置的安全策略(例如Firebase身份验证/规则或Amazon Cognito)通过事件触发的serverless计算使用直接从移动设备访问BaaS的移动应用程序。
  • “Throwaway”或短期使用的移动应用程序,例如大型会议的调度应用程序,在会议前后的周末几乎没有需求,但需要极大的扩展和收缩; 在周一和周二早上的活动过程中根据时间表查看要求,然后在午夜时分回到主题演讲。

业务逻辑

当与管理和协调function一起部署时,在业务流程中执行一系列步骤的微服务工作负载的编排是serverless计算的另一个好用例。执行特定业务逻辑的function(例如订单请求和批准,股票交易处理等)可以与有状态管理器一起安排和协调。来自客户端门户的事件请求可以由这样的协调function提供服务,并传递给适当的serverless function。

例子包括:

交易台,处理股票市场交易并处理客户的交易订单和确认。协调器使用状态图管理交易。初始状态接受来自客户端门户的交易请求,并将请求传递给微服务function以解析请求并验证客户端。随后的状态根据买入或卖出交易指导工作流,验证基金余额,股票代码等,并向客户发送确认。在从客户端接收到确认请求事件时,后续状态调用管理交易执行的function,更新账户,并通知客户完成交易。

持续集成管道

传统的CI管道包括一个构建从属主机池,它们处于空闲等待以便分派作业。Serverless是一种很好的模式,可以消除对预配置主机的需求并降低成本。构建作业由新代码提交或PR合并触发。 调用function来运行构建和测试用例,仅在所需的时间内执行,并且在未使用时不会产生成本。这降低了成本,并可通过自动扩展来减少瓶颈以满足需求。

例子包括:

Serverless vs. 其他云原生技术

大多数应用程序开发人员在寻找托管其云原生应用程序的平台时可能会考虑三种主要的开发和部署模型。每个模型都有自己的一组不同的实现(无论是开源项目,托管平台还是本地产品)。这三种型号通常建立在容器技术的基础上,为了密度,性能,隔离和包装特性,但容器化并不是要求。

为了增加抽象,远离运行其代码的实际基础设施,并且更加关注开发的业务逻辑,它们是Container Orchestration(或Containers-as-a-Service),Platform-as-a-Service和Serverless(Functions-as-a-Service)。所有这些方法都提供了部署云原生应用程序的方法,但它们根据其预期的开发人员和工作负载类型确定了不同功能和非功能方面的优先级。以下部分列出了每个模型的一些关键特征。

请记住,没有任何银弹可以满足所有云原生开发和部署挑战。将特定工作负载的需求与每种常见的云原生开发技术的优缺点相匹配非常重要。同样重要的是要考虑应用程序的子组件可能更适合于一种方法而不是另一种方法,因此可以采用混合方式。

Container Orchestration/容器编排

Containers-as-a-Service(CaaS) - 保持对基础设施的完全控制并获得最大的可移植性。 示例:Kubernetes,Docker Swarm,Apache Mesos。

像Kubernetes,Swarm和Mesos这样的容器编排平台允许团队构建和部署可移植应用程序,具有灵活性和对配置的控制,可以在任何地方运行,而无需为不同的环境重新配置和部署。

优势包括最大限度的控制,灵活性,可重用性以及将现有的容器化应用程序引入云中的便利性,所有这些都是可能的,因为不太自由的应用程序部署模型提供了自由度。

CaaS的缺点包括显著地增加开发人员对操作系统(包括安全补丁),负载平衡,容量管理,扩展,日志记录和监控的责任。

目标受众

  • 希望控制其应用程序及其所有依赖项的打包和版本控制的开发人员和运维团队,确保跨部署平台的可移植性和重用。
  • 在一组相互依赖,独立扩展的微服务中寻求高性能的开发人员。
  • 将容器移至云端,或跨私有/公共云部署,以及具有端到端群集部署经验的组织。

开发/运维人员经验

  • 创建Kubernetes集群,Docker Swarm堆栈或Mesos资源池(完成一次)。
  • 在本地迭代和构建容器镜像。
  • 将打好标记的应用程序镜像推送到注册表。
  • 将基于容器镜像的容器部署到集群。
  • 测试并观察生产中的应用。

优点

  • 对于正在部署的内容,开发人员拥有最大程度的控制权和责任。使用容器编排器,可以定义要部署的确切镜像版本,配置,以及管理其运行时的策略。
  • 控制运行时环境(例如,运行时,版本,最小OS,网络配置)。
  • 在系统外,容器镜像具有更高的可重用性和可移植性。
  • 非常适合将容器化应用程序和系统引入云端。

缺点

  • 对文件系统映像和执行环境负有更多责任,包括安全补丁和分发优化。
  • 管理负载平衡和扩展行为的更多责任。
  • 通常更多的责任是容量管理。
  • 通常更长的启动时间,今天。
  • 通常对应用程序结构的看法较少,因此指导意见较少。
  • 通常对构建和部署机制负有更多责任。
  • 通常,对监视,日志记录和其他常见服务的集成负有更多责任。

Platform-as-a-Service

Platform-as-a-Service (PaaS) - 专注于应用程序,让平台处理其余的事务。

示例:Cloud Foundry,OpenShift,Deis,Heroku

Platform-as-a-Service实现使团队能够部署和扩展应用程序,通过将配置信息注入到这些应用程序,可以使用大量运行时,绑定到数据目录,AI,IoT和安全服务,而无需手动配置和管理容器和操作系统。它非常适合具有稳定编程模型的现有Web应用程序。

优点包括更轻松地管理和部署应用程序,自动扩展和预配置服务,以满足最通用的应用程序需求。

缺点包括缺乏操作系统控制、粒度容器可移植性、负载平衡、应用程序优化,还有潜在的供应商锁定,以及需要在大多数PaaS平台上构建和管理监视和日志记录功能。

目标受众

  • 需要部署平台的开发人员,使他们能够专注于应用程序源代码和文件(不打包它们),而不必担心操作系统。
  • 默认情况下,使用可路由主机名创建更传统的基于HTTP的服务(应用程序和API)的开发人员。 但是,一些PaaS平台现在也支持通用TCP路由。
  • 对更为成熟的云计算模型(与serverless相比)感到满意的组织,这些模型有综合文档和许多实例的支持。

开发/运维人员经验

  • 迭代应用程序,在本地Web开发环境中构建和测试。
  • 将应用程序推送到PaaS,在其中构建和运行。
  • 测试并观察生产中的应用。
  • 更新配置以确保高可用性和扩展以匹配需求。

优点

  • 开发人员的参考框架在应用程序代码和它连接的数据服务上。对实际运行时的控制较少,但开发人员避免了构建步骤,也可以选择扩展和部署选项。
  • 无需管理底层操作系统。
  • 构建包提供对运行时的影响,根据需要提供尽可能多的控制(合理的默认值)。
  • 非常适合具有稳定编程模型的许多现有Web应用程序。

缺点

  • 失去对操作系统的控制,可能受到构建包版本的支配。
  • 关于应用程序结构的更多见解,倾向于 12因素 微服务最佳实践,以及架构灵活性的潜在成本。
  • 潜在的平台锁定。

Serverless

Functions-as-a-Service (FaaS)

将逻辑编写为响应各种事件的小块代码。

示例:AWS Lambda,Azure Functions,基于Apache OpenWhisk的IBM Cloud Functions,Google Cloud Functions,华为Function Stage 和 Function Graph,Kubeless,iron.io,funktion,fission,nuclio

Serverless使开发人员能够专注于由事件驱动的函数组成的应用程序,这些函数响应各种触发器并让平台负责其余的事情 - 例如触发器到函数逻辑,从一个函数传递到另一个函数的信息,自动设置容器和运行时间(时间,地点和内容),自动扩展,身份管理等。

其优势包括对任何云原生范例的基础设施管理的最低要求。无需考虑操作系统或文件系统,运行时甚至容器管理。Serverless享受自动扩展,弹性负载平衡和最细粒度的“即用即付”计算模型。

缺点包括不够全面和稳定的文档,示例,工具和最佳实践; 有挑战的调试; 响应时间可能较慢; 缺乏标准化和生态系统成熟度以及平台锁定的可能性。

目标受众

  • 希望在单个函数中更多地关注业务逻辑的开发人员,这些函数可根据需求自动扩展并将交易与成本紧密联系起来。
  • 希望更快地构建应用程序并且更少关注运维方面的开发人员。
  • 创建事件驱动应用程序的开发人员和团队,例如响应数据库更改,物联网读数,人工输入等。
  • 在标准和最佳实践尚未完全建立的领域,能够轻松采用尖端技术的组织。

开发/运维人员经验

  • 迭代函数,在本地Web开发环境中构建和测试。
  • 将单个函数上载到serverless平台。
  • 声明事件触发器,函数及其运行时,以及事件到函数的关系。
  • 测试并观察生产中的应用。
  • 无需更新配置以确保高可用性和扩展以匹配需求。

Benefits优点

  • 开发人员的观点已经远离运维问题,如管理高可用性函数的部署,更多地转向函数逻辑本身。
  • 开发人员可根据需求/工作量自动扩展。
  • 利用新的“即用即付”成本模型,仅对代码实际运行的时间收费。
  • 操作系统,运行时甚至容器生命周期都是完全抽象的(serverless)。
  • 更适合涉及物联网,数据和消息的新兴事件驱动和不可预测的工作负载。
  • 通常是无状态,不可变和短暂的部署。每个函数都以指定的角色和明确定义/有限的资源访问权限运行。
  • 中间件层将得到调整/优化,将随着时间的推移提高应用程序性能。
  • 强烈推广微服务模型,因为大多数serverless运行时强制限制每个单独函数的大小或执行时间。
  • 易于将第三方API集成为定制的serverless API,既可以扩展使用,又可以灵活地从客户端或服务器调用。

缺点

  • 一种新兴的计算模型,快速创新,缺乏全面和稳定的文档,示例,工具和最佳实践。

  • 由于运行时更具动态性,与IaaS和PaaS相比,调试可能更具挑战性。

  • 由于按需结构,如果运行时在空闲时删除函数的所有实例,则某些serverless运行时的“冷启动”方面可能有性能问题。

  • 在更复杂的情况下(例如,触发其他函数的函数),对于相同数量的逻辑,可以存在更多的运维表面区域。

  • 缺乏标准化和生态系统成熟度。

  • 由于平台的编程模型,事件/消息接口和BaaS产品,有平台锁定的可能性。

应该使用哪种云原生部署模型?

为了确定哪种模型最适合您的特定需求,应对每种方法(以及若干模型实施)进行全面评估。本节将提供一些考虑因素的建议,因为没有一个放之四海而皆准的解决方案。

评估特性和能力

体验每种方法。 从功能和开发体验的角度找到最适合您需求的方法。你正试图找到问题的答案,例如:

  • 基于前面部分中描述的工作负载,这是serverless证明其价值的地方,我的应用程序是否适合? 与替代方案相比,我是否预期从serverless获得重大收益而值得改变?

  • 在运行时及其运行环境中,我真正需要多少控制? 小的运行时版本更改会影响我吗? 我可以覆盖默认值吗?

  • 我可以使用我选择的语言提供的全套功能和库吗? 如果需要,我可以安装其他模块吗? 我是否必须自己打补丁或升级?

  • 我需要多少运维控制? 我是否愿意放弃容器或执行环境的生命周期?

  • 如果我需要更改服务代码怎么办? 我可以多快部署它?

  • 我如何保护我的服务? 我必须管理吗? 或者我可以卸载到可以做得更好的服务吗?

评估和衡量运维方面

使用PaaS和Container Orchestrator收集性能数据,例如恢复时间,以及使用Serverless平台进行冷启动。探索并量化应用程序的其他重要非功能特性对每个平台的影响,例如:

弹性:

  • 如何使我的应用程序适应数据中心故障?
  • 在部署更新时如何确保服务的连续性?
  • 如果我的服务失败怎么办? 平台会自动恢复吗? 它对最终用户是不可见的吗?

可扩展性:

  • 如果有突然的变化,平台是否支持自动扩展?
  • 我的应用程序是否设计为有效地利用无状态扩展?
  • 我的serverless平台是否会压倒任何其他组件,例如数据库? 我可以管理或限制背压吗?

性能:

  • 每个实例或每个HTTP客户端每秒有多少个函数调用?
  • 给定工作负载需要多少台服务器或实例?
  • 从调用到响应的延迟是多少(在冷启动和热启动中)?
  • 微服务之间的延迟,与单个部署中的共存功能相比,是问题吗?

CNCF Serverless工作组的潜在成果之一可能是何时选择特定模型的决策框架,以及如何在给定一组推荐工具的情况下进行测试。 有关详细信息,请参阅结论部分。

评估并考虑潜在成本的全部范围

这包括开发成本和运行时资源成本。

  • 不是每个人都可以从头开始开展他们的开发活动。 因此,需要仔细考虑将现有应用程序迁移到其中一个云原生模型的成本。虽然对容器的升降式模型看起来最便宜,但从长远来看,它可能不是最具成本效益的。 同样,从成本角度来看,serverless的按需模型非常具有吸引力,但将单体应用程序拆分为函数所需的开发工作可能令人生畏。
  • 与依赖服务集成的成本是多少? Serverless计算最初可能看起来最经济,但它可能需要更昂贵的第三方服务成本,或者非常快速地自动缩放,这可能导致更高的使用费。
  • 平台免费提供哪些功能/服务? 我是否愿意以可移植性的潜在成本购买供应商的生态系统?

基于多平台运行应用程序

在查看当前可用的各种云托管技术时,可能并不明显,但没有理由需要将单个解决方案用于所有部署。实际上,没有理由需要在单个应用程序中使用相同的解决方案。一旦将应用程序拆分为多个组件或微服务,您就可以自由地将每个组件分别部署在完全不同的基础设施上,如果这是最符合您需求的。

同样,每个用于其特定目的微服务也可以用最佳技术(即语言)开发。 “分解单体”带来的自由带来了新的挑战,以下部分重点介绍了在选择平台和开发微服务时应该考虑的一些方面。

跨部署目标拆分组件

考虑将正确的技术与正确的工作相匹配,例如,物联网演示可能同时使用PaaS应用程序处理对连接设备仪表板的请求,以及一组 serverless 函数来处理来自设备本身的MQTT消息事件。 Serverless不是一个银弹,而是在您的云原生架构中可以考虑的新选择。

设计多个部署目标

另一种设计选择是使您的代码尽可能通用,允许在本地进行测试,并依赖于上下文信息(如环境变量)来影响它在特定环境中的运行方式。 例如,一组普通的POJO可能能够在三个主要环境中的任何一个中运行,并且可以根据可用的环境变量,类库或绑定服务来定制精确的行为。

为任意方式继续使用DevOps管道

大多数容器编排平台,PaaS实现和serverless框架都可以由命令行工具驱动,并且相同的容器镜像可以构建一次并在每个平台上重用。

考虑抽象以简化模型之间的可移植性

有越来越多的第三方项目生态系统弥补了将当前在PaaS或CaaS上运行的基于HTTP的Web应用程序移植到serverless平台的差距。 其中包括来自Serverless, Inc.和Zappa Framework的几个工具。

Serverless框架提供的适配器使得使用流行的Web应用程序框架(如Python WSGi和JAX-RS REST API)编写的应用程序能够在Serverless平台上运行。这些框架还可以提供可移植性和多个Serverless平台之间差异性的抽象。

详细信息视图:Serverless处理模型

本节总结了serverless框架中当前的函数使用,并概括了serverless 函数需求,生命周期,调用类型和所需的抽象。 我们的目标是定义serverless 函数规范,以便相同的函数可以编码一次并在不同的serverless框架中使用。 本节未定义确切的函数配置和API。

我们可以将FaaS解决方案概括为具有下图中显示的几个关键元素:

  • Event sources/事件源 - 触发事件或流式传输触发到一个或多个函数实例中
  • Function instances/函数实例 - 单个函数/微服务,可以按需扩展
  • FaaS Controller/FaaS控制器- 部署,控制和监视函数实例及其来源
  • Platform services/平台服务 - FaaS解决方案使用的一般集群或云服务(有时称为Backend-as-a-Service)

让我们首先看一下serverless环境中函数的生命周期。

函数生命周期

以下部分描述了函数生命周期的各个方面以及serverless框架/运行时通常如何管理它们。

函数部署管道

函数的生命周期从编写代码并提供规范和元数据开始(参见下面的函数定义),“builder”实体将获取代码和规范,编译并将其转换为工件(代码二进制文件,包或容器镜像)。 然后将工件部署在具有控制器实体的集群上,该控制器实体负责基于事件流量和/或实例上的负载来扩展函数实例的数量。

函数操作

Serverless框架可以允许以下动作和方法来定义和控制函数生命周期:

  • Create - 创建新函数,包括其规格和代码
  • Publish - 创建可在群集上部署的函数新版本
  • Update Alias/Label (版本的) - 更新别名/标签(版本) - 更新版本别名
  • Execute/Invoke - 调用特定版本,不通过其事件源
  • Event Source association - 将特定版本的函数与事件源连接
  • Get - 返回函数元数据和规范
  • Update - 修改函数的最新版本
  • Delete - 删除函数,可以删除特定版本或其所有版本的函数
  • List - 显示函数列表及其元数据
  • Get Stats - 返回有关函数运行时使用情况的统计信息
  • Get Logs - 返回函数生成的日志

在创建函数时,提供其元数据(稍后在函数规范中描述)作为函数创建的一部分,函数将被编译并可能被发布。 稍后可以启动,禁用和启用函数。函数部署需要能够支持以下用例:

  • Event streaming/事件流,在此用例中,队列中可能始终存在事件,而处理的暂停/恢复可能需要通过显式请求

  • Warm startup/热启动 - 在任何时候具有最少实例数量的函数,在接收的“first”事件时进行热启动,因为该函数已经部署并准备好为事件服务(而不是冷启动,冷启动时指函数获得通过“incoming”事件在第一次调用时部署)

用户可以发布函数,这将创建新版本(“latest”版本的副本),发布的版本可能被标记或具有别名,请参阅下文。

用户可能希望直接执行/调用函数(绕过事件源或API gateway)以进行调试和开发过程。用户可以指定调用参数,例如所需版本,同步/异步操作,详细级别等。

用户可能想要获得函数统计(例如调用次数,平均运行时间,平均延迟,失败,重试等),统计可以是当前度量值或时间序列值(例如存储在Prometheus或云提供者设施中例如AWS Cloud Watch)。

用户可能希望检索函数日志数据。这可以通过严重性级别和/或时间范围和/或内容来进行过滤。 Log数据是每个函数都有的,它包括诸如函数创建和删除,显式错误,警告或调试消息之类的事件,以及可选的函数Stdout或Stderr。倾向每次调用有一个日志条目或者将日志条目与特定调用相关联的方式(以允许更简单地跟踪函数执行流程)。

Function Versioning and Aliases

A Function may have multiple versions, providing the user the ability to run different level of codes such as beta/production, A/B testing etc. When using versioning, the function version is “latest” by default, the “latest” version can be updated and modified, potentially triggering a new build process on every such change.

Once a user wants to freeze a version he will use a Publish operation that will create a new version with potential tags or aliases (e.g. “beta”, “production”) to be used when configuring an event source, so an event or API call can be routed to a specific function version. Non-latest function versions are immutable (their code and all or some of the function spec) and cannot be changed once published; functions cannot be “un-published” instead they should be deleted.

Note that most implementations today do not allow function branching/fork (updating an old version code) since it complicates the implementation and usage, but this may be desired in the future.

When there are multiple versions of the same function, the user must specify the version of the function he would like to operate and how to divide the traffic of events between the different versions (e.g. a user can decide to route 90% of an event traffic to a stable version and 10% to a beta version a.k.a “canary update”). This can be either by specifying the exact version or by specifying the version alias. A version alias will typically reference to a specific function version.

When a user creates or updates a function, it may drive a new build and deployment depending on the nature of the change.

1.2 - Serverless使用场景

Serverless使用场景

从aws lambda,azure functions和cncf serverless白皮书中整理出来的各种serverless典型使用场景。

后端

AWS Lambda:您可以使用 AWS Lambda 构建无服务器后端,以处理 Web、移动、物联网 (IoT) 和第 3 方 API 请求。

Web 应用程序后端

Azure的描述

从队列中获取在线订单,并进行处理,生成的数据保存在数据库中。

分析:

  • 需要通过 Service Bus ,处理结果存储到Azure自家的 Cosmos DB。

Aws Lambda的描述

通过将 AWS Lambda 与其他 AWS 服务相结合,开发人员可以构建功能强大的 Web 应用程序,从而可自动扩展和收缩,并跨多个数据中心在高可用配置中运行,而无需在可扩展性、备份或多数据中心冗余方面执行任何管理工作。

实际案例:Bustle 使用 AWS Lambda 和 Amazon API Gateway 为其 Bustle iOS 应用程序和网站运行了一个无服务器后端。借助无服务器架构,Bustle 无需管理基础设施,因此每位工程师都能够集中精力构建新功能并进行创新。

场景分析:

  • web请求通过REST走API Gateway进来,触发Lambda
  • Lambda返回数据给请求
  • 标准的对BaaS后端的请求

移动应用程序后端

Azure的描述

同事之间通过使用手机银行支付午餐费用:垫付午餐费用的人通过移动应用请求付款,这将在其他同事的手机上触发通知。

分析:

  • 跳过了Service Bus,应该只是图上忽略了吧?
  • 同样处理结果进Cosmos DB
  • 存Cosmos DB时再次出发其他function
  • 继续通过使用 Notifications Hub 发送通知

Aws Lambda的描述

您可以使用 AWS Lambda 和 Amazon API Gateway 构建后端,以验证和处理 API 请求。Lambda 能够轻松创造丰富、个性化的应用程序体验。

实际案例:Bustle 使用 AWS Lambda 和 Amazon API Gateway 为其 Bustle iOS 应用程序和网站运行了一个无服务器后端。借助无服务器架构,Bustle 无需管理基础设施,因此每位工程师都能够集中精力构建新功能并进行创新。

场景分析:

  • 移动应用程序更新状态,通过REST请求走API Gateway进来,触发Lambda
  • Lambda处理并发起状态更新通知,push给Amazon SNS

IOT 后端

Aws Lambda的描述

您可以使用 AWS Lambda 构建无服务器后端,以处理 Web、移动、物联网 (IoT) 和第 3 方 API 请求。

场景分析:

  • 传感器发送数据给Kinesis流数据处理平台
  • Kinesis捕获传感器数据并流式传输传感器数据,触发Lambda

数据处理

Aws lambda:您可以使用 AWS Lambda 执行代码以响应数据更改、系统状态变化或用户操作等触发器。Lambda 可以由 S3、DynamoDB、Kinesis、SNS 和 CloudWatch 等 AWS 产品直接触发,也可以通过 AWS Step Functions 编排到工作流程中。您可借此构建各种实时的无服务器数据处理系统。

数据库更改或更改数据捕获(CDC)

CNCF白皮书:在此场景中,当从数据库插入,修改或删除数据时调用function。在这种情况下,它的功能类似于传统的SQL触发器,几乎就像是与主同步流并行的副作用或动作。其结果是执行一个异步逻辑,可以修改同一个数据库中的某些内容(例如记录到审计表),或者依次调用外部服务(例如发送电子邮件)或更新其他数据库,例如 DB CDC(更改数据捕获)用例的情况。 由于业务需要和处理变更的服务分布的原因,这些用例的频率以及对原子性和一致性的需要可能不同。

例子包括:

  • 审核对数据库的更改,或确保它们满足特定质量或分析标准以进行可接受的更改。
  • 在输入数据时或之后不久自动将数据翻译为其他语言。

实时文件处理

Azure的描述

病历以 PDF 文件形式安全上传。然后使用 OCR 检测分解和处理该数据,并将其添加到数据库以便查询。

分析:

  • 触发来自Blob Storage
  • function进行处理,转交给OCR处理的服务
  • 再将结构化信息存储在数据库中

Aws Lambda的描述

您可以使用 Amazon S3 触发 AWS Lambda,以便在上传数据后立即对它们进行处理。例如,您可以使用 Lambda 实时创建缩略图、转换视频代码、建立文件索引、处理日志、验证内容以及聚合和筛选数据。

实际案例:西雅图时报利用 AWS Lambda 来调整图像大小,以便于在不同的设备(如台式机、平板电脑和智能手机)上查看。

场景分析:

  • 相机拍照,图片上传,触发Lambda (同样是Blob Storage触发)
  • 对图片进行处理如修改大小
  • 但这里没有说处理之后的图片如何存储,应该也是类似的存储在s3中

实时流式处理

Azure的描述

从大量云应用收集到大量遥测数据。近乎实时地处理该数据,并将其存储到 DB 中,供分析仪表板使用。

分析:

  • 应用或者设备产生数据,作为遥测信息收集
  • function处理遥测数据,将结果发送给 Cosmos DB
  • 按照实际经验,这里的function应该会是多次流处理,不会简单的一个function

Aws Lambda的描述

您可以使用 AWS Lambda 和 Amazon Kinesis 处理实时流数据,从而跟踪应用程序活动、处理事务处理顺序、分析单击数据流、整理数据、生成指标、筛选日志、建立索引、分析社交媒体以及遥测和计量 IoT 设备数据。

实际案例:Localytics 可实时处理数十亿个数据点,并使用 Lambda 来处理存储在 S3 中或从 Kinesis 进行流式处理的历史和活动数据。

场景分析:

  • 社交媒体数据实时上载,触发Lambda
  • Lambda生成趋势数据,存储到 DynamoDb
  • 趋势数据可以被立即查看

提取、转换、加载

Aws Lambda的描述

您可以使用 AWS Lambda 针对 DynamoDB 表中的每个数据更改执行数据验证、筛选、排序或其他转换,并将转换后的数据加载到其他数据存储。

实际案例:Zillow 使用 Lambda 和 Kinesis 实时跟踪移动指标子集。凭借 Kinesis 和 Lambda,我们得以在两周内开发和部署一套成本高效的解决方案。

场景分析:

  • 订单操作更新数据库,触发Lambda
  • Lambda进行转换,将数据存储到数据仓库

## 其他

计划任务的自动化

Azure的描述

每 15 分钟对客户数据库执行一次分析,检查是否有重复条目,避免将多个通信发送给同一个客户。

分析:

  • function定时调度,定期清理数据

CNCF白皮书的描述

批处理作业或计划任务: 每天只需几分钟就能以异步方式进行强大的并行计算,IO或网络访问的作业非常适合serverless。作业可以在以弹性方式运行时有效地消费他们所需的资源,并且在不被使用的当天剩余时间内不会产生资源成本。

例子包括:

  • 计划任务可以是每晚运行的备份作业。
  • 并行发送许多电子邮件的作业会扩展function实例。

扩展 SaaS 应用程序

Azure的描述

SaaS 解决方案通过 webhook(可通过 Functions 实现)提供扩展性,以自动执行某些工作流。

分析:

  • 外部活动,通过web hook触发function
  • function进行处理,或者通过事件继续触发其他function

持续集成管道

CNCF白皮书:传统的CI管道包括一个构建从属主机池,它们处于空闲等待以便分派作业。Serverless是一种很好的模式,可以消除对预配置主机的需求并降低成本。构建作业由新代码提交或PR合并触发。 调用function来运行构建和测试用例,仅在所需的时间内执行,并且在未使用时不会产生成本。这降低了成本,并可通过自动扩展来减少瓶颈以满足需求。

业务逻辑

CNCF白皮书:当与管理和协调function一起部署时,在业务流程中执行一系列步骤的微服务工作负载的编排是serverless计算的另一个好用例。执行特定业务逻辑的function(例如订单请求和批准,股票交易处理等)可以与有状态管理器一起安排和协调。来自客户端门户的事件请求可以由这样的协调function提供服务,并传递给适当的serverless function。

例子包括:

交易台,处理股票市场交易并处理客户的交易订单和确认。协调器使用状态图管理交易。初始状态接受来自客户端门户的交易请求,并将请求传递给微服务function以解析请求并验证客户端。随后的状态根据买入或卖出交易指导工作流,验证基金余额,股票代码等,并向客户发送确认。在从客户端接收到确认请求事件时,后续状态调用管理交易执行的function,更新账户,并通知客户完成交易。

聊天机器人

CNCF白皮书:与人类交互不一定需要毫秒级别的响应时间,并且在许多方面,稍微延迟让回复人类的机器人对话感觉更自然。因此,等待从冷启动加载function的初始等待时间可能是可接受的。当添加到Facebook,WhatsApp或Slack等流行的社交网络时,机器人可能还需要具有极高的可扩展性,因此在PaaS或IaaS模型中预先设置一个永远在线的守护程序,以预测突然或高峰需求,可能不会有作为serverless方法的高效或成本效益。

例子包括:

  • 支持和销售机器人插入到大型社交媒体服务,如Facebook或其他高流量网站。
  • 消息应用程序Wuu使用Google Cloud Functions使用户能够创建和共享在数小时或数秒内消失的内容。
  • 另请参阅下面的HTTP REST API和Web应用程序。

1.3 - Serverless资料收集

serverless资料收集

官方资料

虽然Serverless没有真正的所谓官方资料,不过有些资料由于权威性比较高,有资格单独列出来:

学习资料

2018年:

2017年:

2016年:

2 - Serverless核心技术

介绍Serverless的核心技术

2.1 - EDA事件驱动架构

EDA事件驱动架构

2.1.1 - Gartner报告

Gartner报告

Gartner Says CIOs Must Define an Event-Centric Digital Business Strategy

备注:内容出处

到2018年, EDA(Event-Driven Architecture)事件驱动架构将成为支持数字业务转型的基本技能。

根据Gartner公司的说法,到2020年,在事件驱动的IT中实现广泛的能力将是大多数全球企业CIO的首要任务。定义以事件为中心的数字业务战略将是实现许多CEO的增长议程的关键 将其视为业务的最高优先事项。

“事件驱动架构(EDA)是实现这一目标的关键技术方法,”Gartner副总裁兼杰出分析师Anne Thomas表示。 “数字业务需要对事件做出快速响应。组织必须能够响应并利用’业务时刻',而这些实时要求正在推动CIO们使他们的应用软件更加受事件驱动。”

定义以事件为中心的数字商业战略

由于CEO专注于通过数字业务发展,CIO应着重于定义以事件为中心的数字业务战略,并阐明EDA的业务价值。根据Gartner 2017 CEO的调查结果,58%的CEO认为增长是企业的首要任务。CEO通过采用新的商业模式,引入新产品和服务,扩展到新市场和地理位置,向现有客户推销和窃取竞争对手的市场份额来实现增长。

“调查结果清楚地表明,CEO认为数字业务是增长的第一个机会,”托马斯说。大多数CEO也认识到技术,产品改进和增长之间的三角关系,他们认识到技术是数字转型的根本推动者,领先的数字公司已经认识到EDA是“秘密酱”,给他们带来竞争优势。

以事件为中心的处理是数字业务的本地架构,并通过数字业务实现增长,应用程序组合的战略部分将需要成为事件驱动的。CIO可以通过实现数字业务转型,利用数字业务时刻,利用现代技术,加快业务敏捷性和实现应用程序现代化,从而促进增长。

使用创新的基于EDA的技术来支持数字业务转型

托马斯说:“事件处理和分析在允许组织利用业务时刻发挥重要作用。事件的融合将产生一个商业机会,这些事件的实时分析以及当前数据和更广泛的上下文数据可用于影响决策并产生成功的业务成果。”

这就是为什么数字业务依赖于EDA。系统(客户,事物和人工智能(AI))产生的事件必须进行数字化,才能被实时识别和处理。EDA将成为2018年支持转型的重要技能,这意味着应用架构和开发团队必须开发EDA能力来准备明年的需求。CIO应该确定目前的项目,EDA可以提供最大的价值,以便采用诸如微服务,物联网(AIT),AI,机器学习,封锁和智能合同等技术创新。

现代化应用组合支持数字业务转型

传统应用程序组合可能是数字业务转型的重要障碍。数字商业技术基础必须支持持续可用性,巨大的可扩展性,自动恢复和动态可扩展性。数字业务应用程序还必须使用现代技术来吸引客户,支持数字业务生态系统,利用数字时刻,并利用AI和物联网。

托马斯说:“核心应用系统的现代化需要时间,很少有组织能够立即转向更换系统。相反,他们需要使用EDA来进行现代化建设,逐步实现数字化转型的能力。”

Gartner客户可以在报告中了解更多信息: “Articulating the Business Value of Event-Driven Architecture."。 更多信息可以在““Champion Event Thinking to Excel at Digital Business."”中找到。 该报告是致力于数字业务中事件处理的18个研究文档的主播。

2.2 - Eventing

Eventing

2.2.1 - Eventing

介绍Eventing

Event功能点

自定义事件源

根据规范可以自由定制业务自己想要的事件源来触发Event

任务完成提供回调功能

事件触发后等待任务完成,完成后可以回调业务配置的接口

事件编排——工作流引擎

  • 提供工作流定制的功能,让用户可以在Event上配置各种事件的依赖关系
  • 支持顺序事件、分支事件和并行事件

性能

  • 高吞吐处理事件源

事件权限隔离

业务只能编排自己创建的事件,外部触发事件流时,也只能触发自己创建的事件流

监控功能

可监控各个业务的单个事件、事件链路耗时等指标

操作平台

供用户编排事件,查看事件结点日志等

对外API提供

可提供通用hook供业务使用,用来触发事件链路的根节点

横向扩展能力

具有横向扩展能力来应对持续增长的事件处理

全局唯一事件id

提供唯一事件id,在并行事件中可以等到该id的所有前置步骤完成后,才触发下一步行为;不同id的 前置步骤不会触发其他id的下一步行为

下游扩展能力

事件触发后,除http调用外,还提供如RPC等其他协议来触发下游任务

调试功能

提供单步调试功能,可直接调试事件链路中的任意相连结点组合

2.3 - function

function

2.3.1 - Function

介绍function

Function功能点

函数调用

  • 可以使用多种语言,只需要提供一个代码片段即可运行
  • 函数之间可以调用
  • 函数执行超时时间
  • 支持代码中使用第三方依赖

调试

  • 本地IDE开发调试
  • 在界面上调试,能够快速的部署,收集调试的日志

构建

从源码到服务,自动构建,支持不同语言,第三方依赖

集成

能够方便的调用其他服务(如存储、数据库等)

版本

  • 支持多个版本
  • 支持蓝绿测试

权限验证

包括外部请求接口的权限以及函数内部调用其他服务的权限

性能

高性能

数据输入输出绑定

输入输出数据源的绑定(比如数据源可以是http、kafka队列)

日志

统一收集调用日志

自动伸缩容

  • 按指标(请求数、cpu)对业务进行快速扩容,扩容过程业务最好无感知,对服务性能无影响。
  • 能缩容到0,减少常驻服务降低成本。

启动时间

冷启动时间尽可能缩短,如果使用k8s,包含k8s启动容器时间 + 业务进程启动时间。解决从0->1和1->n快速扩容的问题。

工作流

能够编排工作流,按步骤调用函数

计费(可选)

只为使用的资源付费,能够采集cpu时间、耗时用于计费

2.4 - serverless

serverless

2.4.1 - CNCF Serverless Whitepaper v1.0

CNCF Serverless Whitepaper v1.0

CNCF Serverless Whitepaper v1.0

备注:内容翻译自 https://github.com/cncf/wg-serverless/tree/master/whitepapers/serverless-overview

本文描述了新型云原生计算模型,该模型由新兴的“serverless”架构及其支持平台实现。它定义了serverless计算的内容,重点介绍了serverless计算的用例和成功示例,并展示了serverless计算如何与其他云应用程序开发模型(如Infrastructure-as-a-Service (IaaS), Platform-as-a-Service (PaaS),容器编排或Container-as-a-Service(CaaS)。

本文包含对通用serverless平台机制的逻辑描述,还有和这些平台相关的编程模型和消息格式,但它没有规定标准。它介绍了几种行业serverless平台及其功能,但不推荐特定实现。

最后,还有关于CNCF如何推进云原生计算的serverless计算的一系列建议。

工作组主席/TOC发起人: Ken Owens (Mastercard)

作者 (按姓氏字母顺序排列):

Sarah Allen (Google), Chris Aniszczyk (CNCF), Chad Arimura (Oracle), Ben Browning (Red Hat), Lee Calcote (SolarWinds), Amir Chaudhry (Docker), Doug Davis (IBM), Louis Fourie (Huawei), Antonio Gulli (Google), Yaron Haviv (iguazio), Daniel Krook (IBM), Orit Nissan-Messing (iguazio), Chris Munns (AWS), Ken Owens (Mastercard), Mark Peek (VMWare), Cathy Zhang (Huawei)

其他贡献者 (按姓氏字母顺序排列):

Kareem Amin (Clay Labs), Amir Chaudhry (Docker), Sarah Conway (Linux Foundation), Zach Corleissen (Linux Foundation), Alex Ellis (VMware), Brian Grant (Google), Lawrence Hecht (The New Stack), Lophy Liu, Diane Mueller (Red Hat), Bálint Pató, Peter Sbarski (A Cloud Guru), Peng Zhao (Hyper)

Serverless 计算

什么是serverless计算?

Serverless计算是指构建和运行不需要服务器管理的应用程序的概念。它描述了一种更细粒度的部署模型,应用程序捆绑一个或多个function,上载到平台,然后执行,缩放和计费,以响应当前所需的确切需求。

Serverless计算并不意味着我们不再使用服务器来托管和运行代码;这也不意味着不再需要运维工程师。相反,它指的是serverless计算的消费者不再需要花费时间和资源来进行服务器配置,维护,更新,扩展和容量规划。相反,所有这些任务和功能都由serverless平台处理,并完全从开发人员和IT/运维团队中抽象出来。因此,开发人员专注于编写应用程序的业务逻辑。运维工程师能够将重点更多的放到关键业务任务上。

Serverless有两个主要角色:

  • Developer/开发人员:为serverless平台编写代码并从中获益,serverless平台提供了这样的视角:没有服务器,而代码始终在运行。
  • Provider/供应商:为外部或内部客户部署serverless平台。

运行serverless平台仍然需要服务器。供应商需要管理服务器(或虚拟机和容器)。即使在空闲时,供应商也会有一些运行平台的成本。自托管系统仍然可以被视为serverless:通常一个团队充当供应商,另一个团队充当开发人员

Serverless计算平台可以提供以下中的一个或两个:

  1. Functions-as-a-Service (FaaS),通常提供事件驱动计算。开发人员使用由事件或HTTP请求触发的function来运行和管理应用程序代码。 开发人员将代码的小型单元部署到FaaS,这些代码根据需要作为离散动作执行,无需管理服务器或任何其他底层基础设施即可进行扩展。
  2. Backend-as-a-Service (BaaS),它是基于API的第三方服务,可替代应用程序中的核心功能子集。因为这些API是作为可以自动扩展和透明操作的服务而提供的,所以对于开发人员表现为是serverless。

Serverless产品或平台为开发人员带来以下好处:

  1. 零服务器运维:serverless通过消除维护服务器资源所涉及的开销,显着改变了运行软件应用程序的成本模型。

    • 无需配置,更新和管理服务器基础设施。管理服务器,虚拟机和容器对于公司而言是一项重大费用,其中包括人员,工具,培训和时间。Serverless大大减少了这种费用。

    • 灵活的可扩展性:serverless的FaaS或BaaS产品可以即时而精确地扩展,以处理每个单独的传入请求。对于开发人员来说,serverless平台没有“预先计划容量”的概念,也不需要配置“自动缩放”的触发器或规则。缩放可以在没有开发人员干预的情况下自动进行。完成请求处理后,serverless FaaS会自动收缩计算资源,因此不会有空闲容量。

  2. 闲置时无计算成本:从消费者的角度来看,serverless产品的最大好处之一是空闲容量不会产生任何成本。例如,serverless计算服务不对空闲虚拟机或容器收费; 换句话说,当代码没有运行或者没有进行有意义的工作时,不收费。 对于数据库,数据库引擎容量空闲等待请求时无需收费。当然,这不包括其他成本,例如有状态存储成本或添加的功能/功能/特性集。

Serverless技术简史

虽然按需或“花多少用多少”模式的概念可追溯到2006年和一个名为Zimki的平台,但serverless一词的第一次使用是2012年来自Iron.io的IronWorker产品 ,一个基于容器的分布式按需工作平台。

从那以后,公共云和私有云都出现了更多serverless实现。首先是BaaS产品,例如2011年的Parse和2012年的Firebase(分别由Facebook和谷歌收购)。2014年11月,AWS Lambda推出,2016年初在Bluemix上宣布了IBM OpenWhisk on Bluemix(现在是IBM Cloud Functions,其核心开源项目成为Apache OpenWhisk),Google Cloud FunctionsMicrosoft Azure Functions华为Function Stage于2017年推出。还有许多开源serverless框架。每个框架(公共和私有)都具有独特的语言运行时和服务集,用于处理事件和数据。

这只是几个例子; 有关更完整和最新的列表,请参阅 Serverless Landscape 文档。Detail View: Serverless Processing Model 部分包含有关整个FaaS模型的更多详细信息。

Serverless用例

虽然serverless计算广泛使用,但它仍然相对较新。通常,当工作负载为以下情况时,应将serverless方法视为首选:

  • 异步,并发,易于并行化为独立的工作单元
  • 不经常或有零星的需求,在扩展要求方面存在巨大的,不可预测的差异
  • 无状态,短暂的,对瞬间冷启动时间没有重大需求
  • 在业务需求变更方面具有高度动态性,需要加快开发人员的速度

例如,对于常见的基于HTTP的应用程序,在自动扩展和更细粒度的成本模型方面有明显的优势。也就是说,使用serverless平台可能会有一些权衡。 例如,如果function的实例数下降到零,则在一段不活动时间后function启动可能会导致性能下降。因此,选择是否采用serverless架构需要仔细查看计算模型的功能性和非功能性方面。

不适合IaaS,PaaS或CaaS解决方案的非HTTP中心和非弹性规模工作负载现在可以利用serverless架构的按需性质和高效成本模型。其中一些工作负载包括:

  • 执行逻辑以响应数据库更改(insert, update, trigger, delete)
  • 对IoT传感器输入消息(例如MQTT消息)执行分析
  • 流处理(分析或修改动态数据)
  • 管理单次提取,转换和加载的作业,这些作业需要在短时间内进行大量处理(ETL)
  • 通过聊天机器人界面提供认知计算(异步,但有关联)
  • 调度执行时间很短的任务,例如cron或批处理样式调用
  • 服务于机器学习和AI模型(检索一个或多个数据元素,如表格,NLP或图像,并与预先学习的数据模型匹配,以识别文本,面孔,异常等)
  • 持续集成pipeline,按需为构建作业提供资源,而不是保留构建从属主机池等待作业分派

本节介绍serverless架构优秀的现有和新兴工作负载和用例。它还包括从早期成功案例中提取的早期结果,模式和最佳实践的详细信息。

这些场景中的每一个都显示了serverless架构如何解决技术问题,即Iaas,PaaS或CaaS效率低下或无法实现。这些例子是:

  • 在没有按需模型的情况下,有效解决了一个全新的问题
  • 更有效地解决了传统的云问题(性能,成本)
  • 显示“大”的维度,无论是处理的数据大小还是处理的请求
  • 通过低错误率的自动缩放(向上和向下)来显示弹性
  • 以前所未有的速度(从天到小时)为市场带来了解决方案

多媒体处理

一个常见的用例,也是最早具体化的用例之一,是响应新文件上传执行一些转换过程的函数。 例如,如果将图像上载到诸如Amazon S3的对象存储服务,则该事件触发函数,用于创建图像的缩略图版本并将其存储回另一个对象存储桶或Database-as-a-Service。 这是一个相当原子化,可并行化的计算任务示例,该计算任务不经常运行并根据需求进行伸缩。

例子包括:

  • Santander 使用serverless function构建了一个概念验证,使用光学字符识别来处理移动支票存款。 这种类型的工作量变化很大,发薪日的处理需求 - 每两周一次 - 可能比支付期的大部分空闲时间大几倍。

  • 通过将 每个视频帧通过图像识别服务 来自动分类电影,以提取演员,情感和对象; 或处理灾区的无人机镜头以估计损坏的程度。

数据库更改或更改数据捕获(CDC)

在此场景中,当从数据库插入,修改或删除数据时调用function。在这种情况下,它的功能类似于传统的SQL触发器,几乎就像是与主同步流并行的副作用或动作。其结果是执行一个异步逻辑,可以修改同一个数据库中的某些内容(例如记录到审计表),或者依次调用外部服务(例如发送电子邮件)或更新其他数据库,例如 DB CDC(更改数据捕获)用例的情况。 由于业务需要和处理变更的服务分布的原因,这些用例的频率以及对原子性和一致性的需要可能不同。

例子包括:

  • 审核对数据库的更改,或确保它们满足特定质量或分析标准以进行可接受的更改。

  • 在输入数据时或之后不久自动将数据翻译为其他语言。

IoT/物联网传感器输入消息

随着连接到网络的自主设备的爆炸式增加,额外的流量体积庞大,并且使用比HTTP更轻量级的协议。 高效的云服务必须能够快速响应消息并扩展以响应其扩散或突然涌入的消息。Serverless功能可以有效地管理和过滤来自IoT设备的MQTT消息。 它们既可以弹性扩展,也可以屏蔽负载下游的其他服务。

例子包括:

  • GreenQ的卫生用例(垃圾互联网),根据垃圾箱的相对饱满度来优化卡车取件路线。

  • 在物联网设备(如AWS Greengrass)上使用serverless来收集本地传感器数据,对其进行规范化,与触发器进行比较,并将事件推送到聚合单元/云。

大规模流处理

另一种非事务性,非请求/响应类型的工作负载是在可能无限的消息流中处理数据。 函数可以连接到消息源,而消息必须从事件流中读取和处理。 鉴于高性能,高弹性和计算密集型处理工作负载,这对于serverless而言非常重要。 在许多情况下,流处理需要将数据与一组上下文对象(在NoSQL或in-mem DB中)进行比较,或者将数据从流聚合并存储到对象或数据库系统中。

例子包括:

聊天机器人

与人类交互不一定需要毫秒级别的响应时间,并且在许多方面,稍微延迟让回复人类的机器人对话感觉更自然。因此,等待从冷启动加载function的初始等待时间可能是可接受的。当添加到Facebook,WhatsApp或Slack等流行的社交网络时,机器人可能还需要具有极高的可扩展性,因此在PaaS或IaaS模型中预先设置一个永远在线的守护程序,以预测突然或高峰需求,可能不会有作为serverless方法的高效或成本效益。

例子包括:

  • 支持和销售机器人插入到大型社交媒体服务,如Facebook或其他高流量网站。

  • 消息应用程序Wuu使用Google Cloud Functions使用户能够创建和共享在数小时或数秒内消失的内容。

  • 另请参阅下面的HTTP REST API和Web应用程序。

批处理作业或计划任务

每天只需几分钟就能以异步方式进行强大的并行计算,IO或网络访问的作业非常适合serverless。作业可以在以弹性方式运行时有效地消费他们所需的资源,并且在不被使用的当天剩余时间内不会产生资源成本。

例子包括:

  • 计划任务可以是每晚运行的备份作业。
  • 并行发送许多电子邮件的作业会扩展function实例。

HTTP REST API和Web应用程序

传统的请求/响应工作负载仍然非常适合serverless,无论工作负载是静态网站还是使用JavaScript或Python等编程语言按需生成响应。即使它们可能会为第一个用户带来启动成本,但在其他计算模型中存在这种延迟的先例,例如将JavaServer Page初始编译为servlet,或者启动新的JVM来处理额外的负载。好处是单个REST调用(例如,微服务中的GET,POST,UPDATE和DELETE 4端点中的每一个)可以独立扩展并单独计费,即使它们共享公共数据后端。

例子包括:

移动后端

使用serverless进行移动后端任务也很有吸引力。它允许开发人员在BaaS API之上构建REST API后端工作负载,因此他们可以花时间优化移动应用程序,而不是扩展后端。 例子包括:优化视频游戏的图形,而不是在游戏成为病毒式打击时投资服务器; 或者对于需要快速迭代以发现产品/市场适合性,或者上市时间至关重要的消费者业务应用程序。另一个示例是批量通知用户或程序其他异步任务以获得离线优先体验。

例子包括:

  • 需要少量服务器端逻辑的移动应用程序; 开发人员可以将精力集中在原生代码开发上。
  • 使用已配置的安全策略(例如Firebase身份验证/规则或Amazon Cognito)通过事件触发的serverless计算使用直接从移动设备访问BaaS的移动应用程序。
  • “Throwaway”或短期使用的移动应用程序,例如大型会议的调度应用程序,在会议前后的周末几乎没有需求,但需要极大的扩展和收缩; 在周一和周二早上的活动过程中根据时间表查看要求,然后在午夜时分回到主题演讲。

业务逻辑

当与管理和协调function一起部署时,在业务流程中执行一系列步骤的微服务工作负载的编排是serverless计算的另一个好用例。执行特定业务逻辑的function(例如订单请求和批准,股票交易处理等)可以与有状态管理器一起安排和协调。来自客户端门户的事件请求可以由这样的协调function提供服务,并传递给适当的serverless function。

例子包括:

交易台,处理股票市场交易并处理客户的交易订单和确认。协调器使用状态图管理交易。初始状态接受来自客户端门户的交易请求,并将请求传递给微服务function以解析请求并验证客户端。随后的状态根据买入或卖出交易指导工作流,验证基金余额,股票代码等,并向客户发送确认。在从客户端接收到确认请求事件时,后续状态调用管理交易执行的function,更新账户,并通知客户完成交易。

持续集成管道

传统的CI管道包括一个构建从属主机池,它们处于空闲等待以便分派作业。Serverless是一种很好的模式,可以消除对预配置主机的需求并降低成本。构建作业由新代码提交或PR合并触发。 调用function来运行构建和测试用例,仅在所需的时间内执行,并且在未使用时不会产生成本。这降低了成本,并可通过自动扩展来减少瓶颈以满足需求。

例子包括:

Serverless vs. 其他云原生技术

大多数应用程序开发人员在寻找托管其云原生应用程序的平台时可能会考虑三种主要的开发和部署模型。每个模型都有自己的一组不同的实现(无论是开源项目,托管平台还是本地产品)。这三种型号通常建立在容器技术的基础上,为了密度,性能,隔离和包装特性,但容器化并不是要求。

为了增加抽象,远离运行其代码的实际基础设施,并且更加关注开发的业务逻辑,它们是Container Orchestration(或Containers-as-a-Service),Platform-as-a-Service和Serverless(Functions-as-a-Service)。所有这些方法都提供了部署云原生应用程序的方法,但它们根据其预期的开发人员和工作负载类型确定了不同功能和非功能方面的优先级。以下部分列出了每个模型的一些关键特征。

请记住,没有任何银弹可以满足所有云原生开发和部署挑战。将特定工作负载的需求与每种常见的云原生开发技术的优缺点相匹配非常重要。同样重要的是要考虑应用程序的子组件可能更适合于一种方法而不是另一种方法,因此可以采用混合方式。

Container Orchestration/容器编排

Containers-as-a-Service(CaaS) - 保持对基础设施的完全控制并获得最大的可移植性。 示例:Kubernetes,Docker Swarm,Apache Mesos。

像Kubernetes,Swarm和Mesos这样的容器编排平台允许团队构建和部署可移植应用程序,具有灵活性和对配置的控制,可以在任何地方运行,而无需为不同的环境重新配置和部署。

优势包括最大限度的控制,灵活性,可重用性以及将现有的容器化应用程序引入云中的便利性,所有这些都是可能的,因为不太自由的应用程序部署模型提供了自由度。

CaaS的缺点包括显著地增加开发人员对操作系统(包括安全补丁),负载平衡,容量管理,扩展,日志记录和监控的责任。

目标受众

  • 希望控制其应用程序及其所有依赖项的打包和版本控制的开发人员和运维团队,确保跨部署平台的可移植性和重用。
  • 在一组相互依赖,独立扩展的微服务中寻求高性能的开发人员。
  • 将容器移至云端,或跨私有/公共云部署,以及具有端到端群集部署经验的组织。

开发/运维人员经验

  • 创建Kubernetes集群,Docker Swarm堆栈或Mesos资源池(完成一次)。
  • 在本地迭代和构建容器镜像。
  • 将打好标记的应用程序镜像推送到注册表。
  • 将基于容器镜像的容器部署到集群。
  • 测试并观察生产中的应用。

优点

  • 对于正在部署的内容,开发人员拥有最大程度的控制权和责任。使用容器编排器,可以定义要部署的确切镜像版本,配置,以及管理其运行时的策略。
  • 控制运行时环境(例如,运行时,版本,最小OS,网络配置)。
  • 在系统外,容器镜像具有更高的可重用性和可移植性。
  • 非常适合将容器化应用程序和系统引入云端。

缺点

  • 对文件系统映像和执行环境负有更多责任,包括安全补丁和分发优化。
  • 管理负载平衡和扩展行为的更多责任。
  • 通常更多的责任是容量管理。
  • 通常更长的启动时间,今天。
  • 通常对应用程序结构的看法较少,因此指导意见较少。
  • 通常对构建和部署机制负有更多责任。
  • 通常,对监视,日志记录和其他常见服务的集成负有更多责任。

Platform-as-a-Service

Platform-as-a-Service (PaaS) - 专注于应用程序,让平台处理其余的事务。

示例:Cloud Foundry,OpenShift,Deis,Heroku

Platform-as-a-Service实现使团队能够部署和扩展应用程序,通过将配置信息注入到这些应用程序,可以使用大量运行时,绑定到数据目录,AI,IoT和安全服务,而无需手动配置和管理容器和操作系统。它非常适合具有稳定编程模型的现有Web应用程序。

优点包括更轻松地管理和部署应用程序,自动扩展和预配置服务,以满足最通用的应用程序需求。

缺点包括缺乏操作系统控制、粒度容器可移植性、负载平衡、应用程序优化,还有潜在的供应商锁定,以及需要在大多数PaaS平台上构建和管理监视和日志记录功能。

目标受众

  • 需要部署平台的开发人员,使他们能够专注于应用程序源代码和文件(不打包它们),而不必担心操作系统。
  • 默认情况下,使用可路由主机名创建更传统的基于HTTP的服务(应用程序和API)的开发人员。 但是,一些PaaS平台现在也支持通用TCP路由。
  • 对更为成熟的云计算模型(与serverless相比)感到满意的组织,这些模型有综合文档和许多实例的支持。

开发/运维人员经验

  • 迭代应用程序,在本地Web开发环境中构建和测试。
  • 将应用程序推送到PaaS,在其中构建和运行。
  • 测试并观察生产中的应用。
  • 更新配置以确保高可用性和扩展以匹配需求。

优点

  • 开发人员的参考框架在应用程序代码和它连接的数据服务上。对实际运行时的控制较少,但开发人员避免了构建步骤,也可以选择扩展和部署选项。
  • 无需管理底层操作系统。
  • 构建包提供对运行时的影响,根据需要提供尽可能多的控制(合理的默认值)。
  • 非常适合具有稳定编程模型的许多现有Web应用程序。

缺点

  • 失去对操作系统的控制,可能受到构建包版本的支配。
  • 关于应用程序结构的更多见解,倾向于 12因素 微服务最佳实践,以及架构灵活性的潜在成本。
  • 潜在的平台锁定。

Serverless

Functions-as-a-Service (FaaS)

将逻辑编写为响应各种事件的小块代码。

示例:AWS Lambda,Azure Functions,基于Apache OpenWhisk的IBM Cloud Functions,Google Cloud Functions,华为Function Stage 和 Function Graph,Kubeless,iron.io,funktion,fission,nuclio

Serverless使开发人员能够专注于由事件驱动的函数组成的应用程序,这些函数响应各种触发器并让平台负责其余的事情 - 例如触发器到函数逻辑,从一个函数传递到另一个函数的信息,自动设置容器和运行时间(时间,地点和内容),自动扩展,身份管理等。

其优势包括对任何云原生范例的基础设施管理的最低要求。无需考虑操作系统或文件系统,运行时甚至容器管理。Serverless享受自动扩展,弹性负载平衡和最细粒度的“即用即付”计算模型。

缺点包括不够全面和稳定的文档,示例,工具和最佳实践; 有挑战的调试; 响应时间可能较慢; 缺乏标准化和生态系统成熟度以及平台锁定的可能性。

目标受众

  • 希望在单个函数中更多地关注业务逻辑的开发人员,这些函数可根据需求自动扩展并将交易与成本紧密联系起来。
  • 希望更快地构建应用程序并且更少关注运维方面的开发人员。
  • 创建事件驱动应用程序的开发人员和团队,例如响应数据库更改,物联网读数,人工输入等。
  • 在标准和最佳实践尚未完全建立的领域,能够轻松采用尖端技术的组织。

开发/运维人员经验

  • 迭代函数,在本地Web开发环境中构建和测试。
  • 将单个函数上载到serverless平台。
  • 声明事件触发器,函数及其运行时,以及事件到函数的关系。
  • 测试并观察生产中的应用。
  • 无需更新配置以确保高可用性和扩展以匹配需求。

Benefits优点

  • 开发人员的观点已经远离运维问题,如管理高可用性函数的部署,更多地转向函数逻辑本身。
  • 开发人员可根据需求/工作量自动扩展。
  • 利用新的“即用即付”成本模型,仅对代码实际运行的时间收费。
  • 操作系统,运行时甚至容器生命周期都是完全抽象的(serverless)。
  • 更适合涉及物联网,数据和消息的新兴事件驱动和不可预测的工作负载。
  • 通常是无状态,不可变和短暂的部署。每个函数都以指定的角色和明确定义/有限的资源访问权限运行。
  • 中间件层将得到调整/优化,将随着时间的推移提高应用程序性能。
  • 强烈推广微服务模型,因为大多数serverless运行时强制限制每个单独函数的大小或执行时间。
  • 易于将第三方API集成为定制的serverless API,既可以扩展使用,又可以灵活地从客户端或服务器调用。

缺点

  • 一种新兴的计算模型,快速创新,缺乏全面和稳定的文档,示例,工具和最佳实践。

  • 由于运行时更具动态性,与IaaS和PaaS相比,调试可能更具挑战性。

  • 由于按需结构,如果运行时在空闲时删除函数的所有实例,则某些serverless运行时的“冷启动”方面可能有性能问题。

  • 在更复杂的情况下(例如,触发其他函数的函数),对于相同数量的逻辑,可以存在更多的运维表面区域。

  • 缺乏标准化和生态系统成熟度。

  • 由于平台的编程模型,事件/消息接口和BaaS产品,有平台锁定的可能性。

应该使用哪种云原生部署模型?

为了确定哪种模型最适合您的特定需求,应对每种方法(以及若干模型实施)进行全面评估。本节将提供一些考虑因素的建议,因为没有一个放之四海而皆准的解决方案。

评估特性和能力

体验每种方法。 从功能和开发体验的角度找到最适合您需求的方法。你正试图找到问题的答案,例如:

  • 基于前面部分中描述的工作负载,这是serverless证明其价值的地方,我的应用程序是否适合? 与替代方案相比,我是否预期从serverless获得重大收益而值得改变?

  • 在运行时及其运行环境中,我真正需要多少控制? 小的运行时版本更改会影响我吗? 我可以覆盖默认值吗?

  • 我可以使用我选择的语言提供的全套功能和库吗? 如果需要,我可以安装其他模块吗? 我是否必须自己打补丁或升级?

  • 我需要多少运维控制? 我是否愿意放弃容器或执行环境的生命周期?

  • 如果我需要更改服务代码怎么办? 我可以多快部署它?

  • 我如何保护我的服务? 我必须管理吗? 或者我可以卸载到可以做得更好的服务吗?

评估和衡量运维方面

使用PaaS和Container Orchestrator收集性能数据,例如恢复时间,以及使用Serverless平台进行冷启动。探索并量化应用程序的其他重要非功能特性对每个平台的影响,例如:

弹性:

  • 如何使我的应用程序适应数据中心故障?
  • 在部署更新时如何确保服务的连续性?
  • 如果我的服务失败怎么办? 平台会自动恢复吗? 它对最终用户是不可见的吗?

可扩展性:

  • 如果有突然的变化,平台是否支持自动扩展?
  • 我的应用程序是否设计为有效地利用无状态扩展?
  • 我的serverless平台是否会压倒任何其他组件,例如数据库? 我可以管理或限制背压吗?

性能:

  • 每个实例或每个HTTP客户端每秒有多少个函数调用?
  • 给定工作负载需要多少台服务器或实例?
  • 从调用到响应的延迟是多少(在冷启动和热启动中)?
  • 微服务之间的延迟,与单个部署中的共存功能相比,是问题吗?

CNCF Serverless工作组的潜在成果之一可能是何时选择特定模型的决策框架,以及如何在给定一组推荐工具的情况下进行测试。 有关详细信息,请参阅结论部分。

评估并考虑潜在成本的全部范围

这包括开发成本和运行时资源成本。

  • 不是每个人都可以从头开始开展他们的开发活动。 因此,需要仔细考虑将现有应用程序迁移到其中一个云原生模型的成本。虽然对容器的升降式模型看起来最便宜,但从长远来看,它可能不是最具成本效益的。 同样,从成本角度来看,serverless的按需模型非常具有吸引力,但将单体应用程序拆分为函数所需的开发工作可能令人生畏。
  • 与依赖服务集成的成本是多少? Serverless计算最初可能看起来最经济,但它可能需要更昂贵的第三方服务成本,或者非常快速地自动缩放,这可能导致更高的使用费。
  • 平台免费提供哪些功能/服务? 我是否愿意以可移植性的潜在成本购买供应商的生态系统?

基于多平台运行应用程序

在查看当前可用的各种云托管技术时,可能并不明显,但没有理由需要将单个解决方案用于所有部署。实际上,没有理由需要在单个应用程序中使用相同的解决方案。一旦将应用程序拆分为多个组件或微服务,您就可以自由地将每个组件分别部署在完全不同的基础设施上,如果这是最符合您需求的。

同样,每个用于其特定目的微服务也可以用最佳技术(即语言)开发。 “分解单体”带来的自由带来了新的挑战,以下部分重点介绍了在选择平台和开发微服务时应该考虑的一些方面。

跨部署目标拆分组件

考虑将正确的技术与正确的工作相匹配,例如,物联网演示可能同时使用PaaS应用程序处理对连接设备仪表板的请求,以及一组 serverless 函数来处理来自设备本身的MQTT消息事件。 Serverless不是一个银弹,而是在您的云原生架构中可以考虑的新选择。

设计多个部署目标

另一种设计选择是使您的代码尽可能通用,允许在本地进行测试,并依赖于上下文信息(如环境变量)来影响它在特定环境中的运行方式。 例如,一组普通的POJO可能能够在三个主要环境中的任何一个中运行,并且可以根据可用的环境变量,类库或绑定服务来定制精确的行为。

为任意方式继续使用DevOps管道

大多数容器编排平台,PaaS实现和serverless框架都可以由命令行工具驱动,并且相同的容器镜像可以构建一次并在每个平台上重用。

考虑抽象以简化模型之间的可移植性

有越来越多的第三方项目生态系统弥补了将当前在PaaS或CaaS上运行的基于HTTP的Web应用程序移植到serverless平台的差距。 其中包括来自Serverless, Inc.和Zappa Framework的几个工具。

Serverless框架提供的适配器使得使用流行的Web应用程序框架(如Python WSGi和JAX-RS REST API)编写的应用程序能够在Serverless平台上运行。这些框架还可以提供可移植性和多个Serverless平台之间差异性的抽象。

详细信息视图:Serverless处理模型

本节总结了serverless框架中当前的函数使用,并概括了serverless 函数需求,生命周期,调用类型和所需的抽象。 我们的目标是定义serverless 函数规范,以便相同的函数可以编码一次并在不同的serverless框架中使用。 本节未定义确切的函数配置和API。

我们可以将FaaS解决方案概括为具有下图中显示的几个关键元素:

  • Event sources/事件源 - 触发事件或流式传输触发到一个或多个函数实例中
  • Function instances/函数实例 - 单个函数/微服务,可以按需扩展
  • FaaS Controller/FaaS控制器- 部署,控制和监视函数实例及其来源
  • Platform services/平台服务 - FaaS解决方案使用的一般集群或云服务(有时称为Backend-as-a-Service)

让我们首先看一下serverless环境中函数的生命周期。

函数生命周期

以下部分描述了函数生命周期的各个方面以及serverless框架/运行时通常如何管理它们。

函数部署管道

函数的生命周期从编写代码并提供规范和元数据开始(参见下面的函数定义),“builder”实体将获取代码和规范,编译并将其转换为工件(代码二进制文件,包或容器镜像)。 然后将工件部署在具有控制器实体的集群上,该控制器实体负责基于事件流量和/或实例上的负载来扩展函数实例的数量。

函数操作

Serverless框架可以允许以下动作和方法来定义和控制函数生命周期:

  • Create - 创建新函数,包括其规格和代码
  • Publish - 创建可在群集上部署的函数新版本
  • Update Alias/Label (版本的) - 更新别名/标签(版本) - 更新版本别名
  • Execute/Invoke - 调用特定版本,不通过其事件源
  • Event Source association - 将特定版本的函数与事件源连接
  • Get - 返回函数元数据和规范
  • Update - 修改函数的最新版本
  • Delete - 删除函数,可以删除特定版本或其所有版本的函数
  • List - 显示函数列表及其元数据
  • Get Stats - 返回有关函数运行时使用情况的统计信息
  • Get Logs - 返回函数生成的日志

在创建函数时,提供其元数据(稍后在函数规范中描述)作为函数创建的一部分,函数将被编译并可能被发布。 稍后可以启动,禁用和启用函数。函数部署需要能够支持以下用例:

  • Event streaming/事件流,在此用例中,队列中可能始终存在事件,而处理的暂停/恢复可能需要通过显式请求

  • Warm startup/热启动 - 在任何时候具有最少实例数量的函数,在接收的“first”事件时进行热启动,因为该函数已经部署并准备好为事件服务(而不是冷启动,冷启动时指函数获得通过“incoming”事件在第一次调用时部署)

用户可以发布函数,这将创建新版本(“latest”版本的副本),发布的版本可能被标记或具有别名,请参阅下文。

用户可能希望直接执行/调用函数(绕过事件源或API gateway)以进行调试和开发过程。用户可以指定调用参数,例如所需版本,同步/异步操作,详细级别等。

用户可能想要获得函数统计(例如调用次数,平均运行时间,平均延迟,失败,重试等),统计可以是当前度量值或时间序列值(例如存储在Prometheus或云提供者设施中例如AWS Cloud Watch)。

用户可能希望检索函数日志数据。这可以通过严重性级别和/或时间范围和/或内容来进行过滤。 Log数据是每个函数都有的,它包括诸如函数创建和删除,显式错误,警告或调试消息之类的事件,以及可选的函数Stdout或Stderr。倾向每次调用有一个日志条目或者将日志条目与特定调用相关联的方式(以允许更简单地跟踪函数执行流程)。

Function Versioning and Aliases

A Function may have multiple versions, providing the user the ability to run different level of codes such as beta/production, A/B testing etc. When using versioning, the function version is “latest” by default, the “latest” version can be updated and modified, potentially triggering a new build process on every such change.

Once a user wants to freeze a version he will use a Publish operation that will create a new version with potential tags or aliases (e.g. “beta”, “production”) to be used when configuring an event source, so an event or API call can be routed to a specific function version. Non-latest function versions are immutable (their code and all or some of the function spec) and cannot be changed once published; functions cannot be “un-published” instead they should be deleted.

Note that most implementations today do not allow function branching/fork (updating an old version code) since it complicates the implementation and usage, but this may be desired in the future.

When there are multiple versions of the same function, the user must specify the version of the function he would like to operate and how to divide the traffic of events between the different versions (e.g. a user can decide to route 90% of an event traffic to a stable version and 10% to a beta version a.k.a “canary update”). This can be either by specifying the exact version or by specifying the version alias. A version alias will typically reference to a specific function version.

When a user creates or updates a function, it may drive a new build and deployment depending on the nature of the change.

3 - Serverless规范

介绍serverless的各种规范和标准

3.1 - CloudEvents规范

CloudEvents规范

3.1.1 - CloudEvents概述

介绍CloudEvents规范

介绍

CloudEvents是一种以通用方式描述事件数据的规范。CloudEvents旨在简化跨服务,平台及其他方面的事件声明和发送。CloudEvents 最初由 CNCF Severless 工作组提出。

A specification for describing event data in a common way

以通用方式描述事件数据的规范

为什么需要CloudEvents?

事件无处不在,然而事件发布者对事件的描述却往往不尽相同。

  • 一致性:缺乏通用的事件描述方式,意味着开发人员必须为每个事件源编写新的事件处理逻辑。
  • 无障碍环境:没有通用的事件格式意味着没有通用的库、工具和基础设施来跨环境投递事件数据。CloudEvents提供了Go、JavaScript、Java、C#、Ruby和Python的SDK,可用于构建事件路由器、跟踪系统和其他工具。
  • 可移植性:整体上阻碍了我们从事件数据中实现的可移植性和生产力。

什么是CloudEvents?

CloudEvents 是一个以通用方式描述事件数据的规范。CloudEvents旨在大幅简化跨服务、跨平台的事件声明和投递。

CloudEvents是一项新的工作,目前仍在积极开发中。然而,它的工作小组已经收到了令人惊讶的行业兴趣,从主要的云提供商到流行的SaaS公司都有。该规范现在由云原生计算基金会(Cloud Native Computing Foundation/CNCF)负责。

CloudEvents是通过CNCF的Serverless工作组组织的。

1.0版本

2019年10月24日,CloudEvents项目取得了两项重大成果。第一,CNCF的技术监督委员会批准该项目成为 “孵化器 “项目(从而使其从CNCF的 “沙盒"毕业)。第二,CloudEvents规范发布了1.0版本!

这是该规范的第一个主要版本,代表了整个serverless社区中一个真正伟大的团队两年来的努力工作。我们已经有几乎所有主要的云提供商参与其中,还有一些 “终端用户 “公司以及许多个人参与者,他们都在努力工作以制作出一个规范,希望在这一里程碑式的发展过程中,能够继续得到更多的采用。

除了核心的CloudEvents规范外,还有Primer和协议及格式规范,所有这些都可以在GitHub repo中找到。此外,还有六种不同的SDK-Go、JavaScript、Java、C#、Ruby和Python,帮助生产和消费CloudEvents。

CNCF Serverless工作组将决定下一步的工作重点(例如,额外的CloudEvents相关活动,或者解决社区正在经历的其他互操作性痛点)。所以,如果你有兴趣,请加入每周的定期电话会议。此外,还有工作流规范方面的工作正在进行中。

历史

CNCF Severless 工作组最初是由 CNCF 技术监督委员会创立的,旨在调查 Serverless 技术和指导 CNCF 在本领域下一步可能展开的相关工作的建议。其中一项建议是创建一个通用的 Event Format,以在不同云供应商提供的Function 之间实现可移植性和事件流处理的互操作性。CloudEvents 规范因此被创建出来。

尽管 CloudEvents 的工作最初是作为 Serverless 工作组的一部分开展的,当规范到达 v0.1 里程碑之后,TOC 批准了 CloudEvents 成为一个独立的 CNCF 沙盒项目。

TODO:补充发展过程。

集成

支持情况
Azure Event Grid Event Grid原生支持CloudEvents v1.0 JSON实现中的事件和HTTP协议绑定。
Knative Eventing 所有由Knative Eventing service产生和消费的事件数据均符合CloudEvents标准
Serverless.com Event Gateway 函数从事件网关接收的所有事件数据均符合 CloudEvents 标准
OpenFaaS CloudEvent事件是OpenFaaS函数的众多可用触发器之一。
Choria Choria 编排系统发出的所有生命周期和自主代理事件都符合 CloudEvents 的标准。
Oracle Cloud Oracle云基础设施事件服务实现了CloudEvents

3.1.2 - CloudEvents规范

介绍CloudEvents规范

介绍

备注:以下内容来自 https://github.com/cloudevents/spec

CloudEvents logo

事件无处不在。然而,事件生产者倾向于以不同的方式来描述事件。

缺乏通用的描述事件的方式意味着开发人员必须不断地重新学习如何消费事件。这也限制了类库、工具和基础设施在跨环境时发送事件数据的潜力,如SDK、事件路由器或跟踪系统等。我们从事件数据中实现的可移植性和生产力总体上受到了阻碍。

CloudEvents是一个用通用格式描述事件数据的规范,以提供跨服务、跨平台和跨系统的互操作性。

CloudEvents得到了大量的行业关注,从主要的云提供商到流行的SaaS公司都有。CloudEvents由云原生计算基金会(CNCF)主办,于2018年5月15日获批为云原生沙盒级项目。

CloudEvents文档

包括核心规范,可选规范和额外文档三部分。

如果是 CloudEvents 的新手,建议先阅读 Primer,了解规范的目标和设计决策,然后继续阅读核心规范。

由于并非所有事件生产者都会默认生成 CloudEvents,因此有文档描述了将一些常用事件适配到 CloudEvents 的推荐过程,请参阅 CloudEvents Adapters。

流程

CloudEvents项目致力于根据设计目标正式确定规范,设计目标侧重于生成和响应事件的系统之间的互操作性。

为了实现这些目标,项目必须描述:

  • 促进互操作性的事件的公共属性
  • 一个或多个现在正在使用或计划由其成员构建的通用体系结构
  • 如何将事件从生产者传输到消费者,通过至少一种协议
  • 识别并解决互操作性所需的任何其他内容

3.1.3 - CloudEvents入门

介绍CloudEvents规范的入门知识

备注:以下内容来自 https://github.com/cloudevents/spec/blob/v1.0/primer.md

CloudEvents logo

概要

本文不是规范性文档,但本文概述了CloudEvents规范。本文旨在对CloudEvent规范进行补充,以提供对规范制定过程中制定的历史和设计决策的更多背景知识和见解。这使规范本身可以专注于规范性的技术细节。

历史

CNCF无服务器工作组最初是由CNCF技术监督委员会设立的,目的是调查无服务器技术,并为CNCF在这一领域的一些相关活动提出一些可能的下一步建议。其中一项建议是调查创建一种通用的事件格式,以帮助云提供商之间的函数可移植性和事件流处理的互操作性。因此,CloudEvents 规范应运而生。

虽然最初CloudEvents的工作是作为无服务器工作组的一部分完成的,但在规范达到v0.1的里程碑之后,TOC批准了CloudEvents工作,将其作为一个新的独立的CNCF沙盒项目。

CloudEvents的概念

事件(Event)包含和发生(Occurrence)相关的上下文和数据。每一个发生(Occurrence)都由事件的数据唯一标识。

事件代表事实,因此不包括目的地,而消息则传达意图,将数据从源头传送到特定的目的地。

Events represent facts and therefore do not include a destination, whereas messages convey intent, transporting data from a source to a given destination.

Eventing

在服务器端代码中,事件通常用于连接不同的系统,其中一个系统的状态变化会导致另一个系统的代码执行。例如,当源接收到外部信号(如 HTTP 或 RPC)或观察到一个变化的值(如 IoT 传感器或非活动期)时,可能会产生一个事件。

为了说明系统如何使用 CloudEvents,下面的简化图显示了来自源的事件如何触发一个动作。

源(Source)生成消息(Message),其中事件(Event)被封装在协议中。事件到达目的地,触发一个由事件数据提供的动作(Action)。

源是源类型的一个特定实例,它允许staging和测试实例。一个特定源类型的开放源软件可以由多个公司或供应商部署。

事件可以通过各种行业标准协议(如HTTP、AMQP、MQTT、SMTP)、开源协议(如Kafka、NATS)或平台/供应商特定的协议(AWS Kinesis、Azure Event Grid)来递送。

动作处理定义了由特定源的特定事件触发的行为或效果的事件。虽然不在本规范的范围内,但生成事件的目的通常是为了让其他系统能够轻松地对它们无法控制的源中的变化做出反应。源和动作通常是由不同的开发人员建立的。通常情况下,源是一个托管服务,而动作是无服务器函数(如AWS Lambda或Google Cloud Functions)中的自定义代码。

设计目标

CloudEvents通常用于分布式系统中,允许服务在开发过程中松散耦合,独立部署,稍后可以连接起来创建新的应用。

CloudEvents规范的目标是定义事件系统的互操作性,允许服务产生或消费事件,其中生产者和消费者可以独立开发和部署。生产者可以在消费者监听之前产生事件,而消费者可以对尚未产生的事件或事件类表达兴趣。请注意,这项工作所产生的规范侧重于事件格式的互操作性,以及事件在HTTP等各种协议上发送时如何呈现。该规范将不关注事件生产者或事件消费者的处理模型。

CloudEvents 的核心是定义了一组关于系统间传输事件的元数据(被称为属性),以及这些元数据应该如何出现在该消息中。这些元数据是将请求路由到适当的组件并促进该组件对事件进行适当处理所需的最低限度的信息集。因此,虽然这可能意味着事件本身的一些应用数据可能会和作为 CloudEvent 属性集的一部分重复,但这只是为了正确传递和处理消息的目的。不用于此目的的数据应放在事件(数据)本身中。

此外,假定协议层向目标系统传递消息所需的元数据完全由协议处理,因此不包含在 CloudEvents 属性中。有关详细信息,请参阅 “非目标 “部分。

在定义这些属性的同时,还将对如何以不同格式(如 JSON)和协议(如 HTTP、AMQP、Kafka)序列化事件进行规范。

一些协议原生支持将多个事件批量化为一个API调用。为了帮助实现互操作性,是否需要批处理和如何实现批处理由协议决定。详情可在协议绑定或协议规范中找到。CloudEvents 的批处理没有语义意义,也没有顺序。中间人可以添加或删除批处理,也可以将事件分配给不同的批次。

非目标

以下内容被认为超出了本规范的范围。

  • 函数的建立和调用过程
  • 特定语言的运行时API
  • 选择单一身份/访问控制系统
  • 包含协议级的路由信息
  • 事件持久化过程

CloudEvents 规范将不包括协议级的路由信息(例如,发送事件的目标 URL)。这是对CloudEvents概念的新手提出的一个常见建议。经过多次讨论后,工作组得出结论:规范中没有必要包含路由信息:任何协议(如 HTTP、MQTT、XMPP 或 Pub/Sub 总线)都已经定义了路由的语义。例如,CloudEvents HTTP 绑定规定了头和请求正文内容。CloudEvents 不需要在规范中包含目标 URL 才能兼容 HTTP;HTTP 规范已经在 Request-Line 中包含了一个目标 URL。

路由信息不仅是多余的,而且会分散注意力。CloudEvents 应该增加互操作性,并将事件的生产者和消费者解耦。禁止事件格式中的路由信息,可以让CloudEvents重新传递给新的Action,或者通过包含多个通道的复杂中继器传递。例如,如果 Webhook 地址不可用,则原定用于 Webhook 的 CloudEvent 应可投递给死信队列。该死信队列应该能够将事件送入原始事件发出者从未想过的新的Action。

在系统内和跨系统产生和消费的CloudEvents会触发行为,从而产生价值。因此,归档和/或重放事件对于调试或复制来说是非常有价值的。然而,持久化事件会删除传输过程中可用的上下文信息,如生产者的身份和权利、保真验证机制或保密保护。此外,持久化会增加复杂性和挑战,以满足用户的需求。例如,重复使用私钥进行加密或签名,会增加攻击者可用的信息,从而降低安全性。预计可能会定义出有助于满足持久性要求的属性,但预计这些属性将随着行业最佳实践和进步而不断发展。

架构

CloudEvents 规范集定义了四种不同类型的协议元素,它们构成了一个分层架构模型。

  1. 基本规范 定义了由属性(键值对)和相关规则组成的抽象信息模型,这些属性和相关规则构成了CloudEvents。

  2. 扩展 添加了特定的、可能重叠的扩展属性和相关规则集,例如,支持不同的跟踪标准。

  3. 事件格式编码(如 JSON)定义了基本规范的信息模型和所选扩展的编码方式,以将其映射到应用协议的头和有效载荷元素。

  4. 协议绑定,例如 HTTP,定义了 CloudEvent 如何与应用协议的传输帧绑定,在 HTTP 的下是绑定 HTTP 消息。协议绑定并不约束传输帧的使用方式,这意味着HTTP绑定可以与任何HTTP方法以及请求和响应消息一起使用。

如果需要确保更广泛的互操作性,CloudEvents 规范集为使用特定应用协议的事件传递提供了特定的约束。HTTP Webhook 规范并不是 CloudEvents 所特有的,它可以用于将任何类型的单向事件和通知发布到符合的 HTTP 端点。然而,由于其他地方缺乏这样的规范,因此CloudEvents有必要定义它。

协议错误处理

大多数情况下,CloudEvents 规范并没有规定与创建或处理 CloudEvents 相关的处理模型。因此,如果在处理 CloudEvents 过程中出现错误,鼓励遇到错误的软件使用常规的协议级错误报告来报告错误。

属性的版本化

对于某些 CloudEvents 属性,其值所引用的实体或数据模型可能会随着时间的推移而变化。例如,dataschema 可能会引用模式文档的一个特定版本。通常情况下,这些属性值将通过在其值中包含某些特定于版本的字符串作为其值的一部分来区分每个变体。例如,可能会使用版本号(v1、v2)或日期(2018-01-01-01)。

CloudEvents 规范并没有规定要使用任何特定的模式,甚至根本不要求使用版本字符串。此决定权在每个事件制生产者手中。但是,当包含特定版本字符串时,应注意其值的变化,因为事件的消费者可能会依赖现有的值,因此变化可能会被解释为 “破坏性变化”。应该在生产者和消费者之间建立某种形式的沟通,以确保事件消费者知道可能使用的值。一般来说,所有 CloudEvents 属性也是如此。

CloudEvent属性

本节提供了与CloudEvent的一些属性相关的其他背景和设计要点。

id

id 属性是指在与一个事件源相关的所有事件中都是唯一的值(每个事件源都是由其 CloudEvents 的 source 属性值唯一标识的)。虽然所使用的确切值由生产者定义,但可以保证来自单一事件源的 CloudEvents 接收者不会有两个事件共享相同的 id 值。唯一的例外情况是,如果支持事件的某些重播,在这种情况下,可以使用 id 来检测。

由于一个事件的发生可能会产生一个以上的事件,所以在所有这些事件都来自同一个事件源的情况下,每个 CloudEvent 构造的事件都有一个唯一的 id。以创建 DB 条目为例,这一次发生可能会产生一个创建类型为 create 的 CloudEvent 和一个写类型为 write 的 CloudEvent。这些CloudEvents中的每一个都有一个唯一的id。如果希望这两个 CloudEvents 之间有一定的相关性,以表明它们都与同一事件相关,那么 CloudEvent 中的一些附加数据将用于此目的。

在这方面,虽然事件生成者选择的确切值可能是一些随机字符串,或在其他语境中具有某种语义意义的字符串,但对于本CloudEvent属性的目的来说,这些意义并不相关,因此,将id用于唯一性检查之外的其他目的不在本规范的范围内,也不建议使用。

CloudEvent 属性扩展

为了实现既定目标,规范作者将试图限制他们在 CloudEvents 中定义的元数据属性的数量。为此,本项目所定义的属性将分为三类。

  • required / 必须的
  • optional / 可选的
  • extensions / 扩展

正如类别名称所暗示的那样,“必需 “属性将是该组认为在所有用例中对所有事件至关重要的属性,而 “可选 “属性将在大多数情况下使用。这两种情况下的属性都将在规范本身中定义。

当小组确定一个属性不够通用,不能归入这两类,但仍然可以从定义良好的互操作性中受益,那么它们将被归入 “扩展 “类别,并被归入文档化的扩展。该规范定义了这些扩展属性在 CloudEvent 中的出现方式。

在确定提议的属性属于哪个类别时,甚至在确定是否将其包含在其中时,小组会使用用例和用户故事来解释其理由和需求。这些支持信息将被添加到本文档的 “Prior Art “部分。

CloudEvent 规范的扩展属性是指需要包含的额外元数据,以帮助确保 CloudEvent 的正确路由和处理。与事件本身相关且在传输或处理 CloudEvent 中不需要的其他目的的附加元数据,应放在事件(数据)本身的适当扩展点中。

扩展属性应保持最小化,以确保 CloudEvent 能够正确地序列化和传输。例如,事件制作者应考虑向 CloudEvent 添加扩展时可能会遇到的技术限制。例如,HTTP二进制模式使用HTTP头来传输元数据;大多数HTTP服务器会拒绝HTTP header数据过多的请求,限制低至8kb。因此,应该尽量减少扩展属性的总大小和数量。

如果一个扩展变得流行,那么规范作者可能会考虑将其作为核心属性移到规范中。这意味着在正式加入规范之前,扩展机制/进程可以作为一种方式来审核新属性,然后再正式加入到规范中。

JSON扩展

正如在CloudEvents规范的JSON事件格式中的Attributes部分提到的那样,CloudEvent扩展属性被序列化为规范定义的属性的兄弟姐妹–也就是说,在JSON对象的顶层。该规范的作者花了很长时间考虑了所有选项,并决定这是最好的选择。以下是其中的一些道理。

由于规范遵循 semver(语义化版本),这意味着新的属性可以被未来版本的核心规范所定义,而不需要重大的版本号改变–只要这些属性是可选的。在这种情况下,考虑一下现有的消费者会如何处理一个新的(未知)顶层属性。虽然它可以自由地忽略它,因为它是可选的,但在大多数情况下,相信这些属性仍然希望暴露在接收这些事件的应用程序中。这将允许这些应用程序支持这些属性,即使基础设施不支持这些属性。这意味着,未知的顶层属性(不管是谁定义的–不管是未来版本的规范还是事件生产者)很可能不会被忽略。因此,虽然其他一些规范定义了一个特定的属性来放置扩展属性(例如顶层扩展属性),但作者决定,在一个传入的事件中,为未知的属性设置两个不同的位置,可能会导致互操作性问题,也会给开发者带来混乱。

通常情况下,在规范正式采用之前,扩展通常是用来测试规范的新的潜在属性。如果有一个扩展类型的属性,在这个新属性中,这个新属性被序列化了,那么,如果这个属性曾经被核心规范采用,那么它将从扩展属性中晋升(从序列化的角度来看)为顶层属性。如果我们假设这个新属性将是可选的,那么随着它被核心规范采用,它将只是一个小的版本增量,所有现有的消费者仍然应该继续工作。然而,消费者将不知道这个属性将出现在哪里–在扩展属性中或作为顶层属性。这意味着他们可能需要在这两个地方都要找。如果这个属性同时出现在两个地方,但价值不同怎么办?生产者是否需要将其放在两个地方,因为他们可能会有新老消费者?虽然可能有可能定义明确的规则来解决每一个可能出现的问题,但作者决定最好是一开始就简单地避免所有问题,在序列化中只为未知的、甚至是新的属性提供一个位置。此外,还有人指出,现在的HTTP规范也遵循了类似的模式,不再建议在HTTP扩展头中用X-作为前缀。

创建CloudEvents

CloudEvents 规范特意避免过强的规定如何创建 CloudEvents。例如,它不假定原始事件源是为该事件的发生构造相关的 CloudEvents 的同一个实体。这样就可以有多种实现选择。但是,对于规范的实现者来说,了解规范作者的期望值是很有用的,因为这可能有助于确保互操作性和一致性。

如上所述,生成初始事件的实体是否是创建相应的 CloudEvent 的实体是一个实现选择。然而,当构造/填充 CloudEvents 属性的实体代表事件源行事时,这些属性的值是为了描述事件或事件源,而不是计算 CloudEvent 属性值的实体。换句话说,当事件源和 CloudEvents 生产者之间的分工对事件消费者没有实质性的意义时,规范定义的属性通常不会包含任何值来表示这种责任的分工。

这并不是说 CloudEvents 生产者不能为 CloudEvents 添加一些额外的属性,但这些属性不属于规范中互操作性定义的属性范围。这就类似于 HTTP 代理通常会尽量减少对传入消息中定义好的 HTTP 标头的更改,但它可能会添加一些包含代理特定元数据的附加标头。

还值得注意的是,原始事件源和 CloudEvents 生产者之间的这种分离可以是小的或大的。这意味着,即使CloudEvents 生产者不属于原始事件源的生态系统的一部分,但如果它是代表事件源行事,并且它在事件流中的存在对事件消费者来说没有意义,那么上述指导仍然适用。

当一个实体同时充当CloudEvents的接收方和发送方,以转发或转换入站事件为目的时,出站CloudEvent与入站CloudEvent的匹配程度将根据该实体的处理语义而有所不同。如果它作为代理,只是将 CloudEvents 转发到另一个事件消费者,那么出站 CloudEvent 通常与入站 CloudEvent 在规范定义的属性方面看起来与入站 CloudEvent 完全相同 - 请参见上一段关于添加附加属性的内容。

但是,如果这个实体正在对CloudEvent进行某种类型的语义处理,通常会导致数据属性的值发生变化,那么它可能需要被视为一个与原始事件源不同的 “事件源”。因此,预计与事件生产者相关的CloudEvents属性(如源和id)将从传入的CloudEvent中更改。

合格的协议和编码

正如规范中所表达的那样,CloudEvents工作的明确目标是 “以通用的方式描述事件数据”,并 “定义事件系统的互操作性,使服务能够产生或消费事件,生产者和消费者可以独立开发和部署”。

这种互操作性的基础是开放的数据格式和开放的协议,CloudEvents旨在提供这种开放的数据格式,并将其数据格式投射到常用的协议和常用的编码上。

尽管每个软件或服务产品和项目显然可以选择自己喜欢的通信形式,但毫无疑问,对这种产品或项目私有的专有协议并不能促进事件生产者和消费者之间的广泛互操作性的目标。

特别是在消息传递和事件处理领域,过去十年来,业界在开发一个强大的、广泛支持的协议基础上取得了重大进展,比如HTTP 1.1和HTTP/2以及WebSockets或事件网络上的WebSockets或事件,或者是面向连接的消息传递和遥测传输的MQTT和AMQP。

一些被广泛使用的协议已经成为事实上的标准,有些协议是由三家或更多公司组成的顶级联盟组成的强大的生态系统中产生的,有些则是由一家公司发布的强大的项目生态系统中产生的,无论在哪种情况下,都是与前面提到的标准栈的演进同步进行的。

CloudEvents 的努力不应成为一种载体,甚至不应成为暗中认可或推广项目或产品专有协议的工具,因为这将会对 CloudEvents 的最初目标产生反作用。

要使协议或编码符合 CloudEvents 核心事件格式或协议绑定的资格,它必须属于以下任一类别。

  • 该协议具有作为标准的正式地位,具有广泛认可的多厂商协议标准化机构(如 W3C、IETF、OASIS、ISO)的标准地位
  • 该协议在其生态系统类别中具有 “非事实标准 “的地位,这意味着它被广泛使用,以至于被认为是特定应用的标准。实际上,我们希望看到至少有一家厂商中立的开源组织(如Apache、Eclipse、CNCF、.NET基金会)旗下至少有一个开源实现,并且至少有十几家独立的厂商在其产品/服务中使用该协议。

除了正式地位之外,协议或编码是否符合核心 CloudEvents 事件格式或协议绑定的关键标准是,该组是否同意该规范将为与协议或编码产生的产品或项目无关的任何一方带来持续的实际利益。这方面的一个基本要求是,协议或编码的定义方式必须允许独立于产品或项目的代码之外的替代实现。

欢迎将 CloudEvents 的所有其他协议和编码格式纳入指向各自项目自己的公共存储库或网站中的 CloudEvents 绑定信息的列表中。

专有协议和编码

为鼓励采用 CloudEvents,本存储库将收集 CloudEvents 专有协议和编码的专有协议和编码的 CloudEvents 规范,不作任何认可。存储库维护者不负责创建、维护或通知专有规范的维护者与 CloudEvents 规范的偏离。

专有规范将托管在自己的存储库或文档站点中,并在专有规范文件中收集。专有规范应遵循与核心协议和编码的其他规范相同的格式。

专有规范比核心规范的审查要少,随着 CloudEvents 规范的发展,各协议和编码的维护者有责任使规范与 CloudEvents 规范保持同步。如果专有规范过时过久,CloudEvents 可能会将该规范的链接标记为过时或删除。

如果为同一协议创建了多个不兼容的规范,存储库维护者将不知道哪个规范是正确的,并列出所有规范的链接。

Prior Art

TODO:以后再细看。

价值主张

本节介绍了一些解释CloudEvents价值的用例。

  • 跨服务和平台的事件规范化

    主要的事件发布商(如AWS、微软、谷歌等)都在各自的平台上以不同的格式发布事件。甚至有少数情况下,同一提供商上的服务以不同的格式发布事件(如AWS)。这就迫使事件消费者不得不实施自定义逻辑,以实现跨平台、偶尔跨服务在单一平台上读取或合并事件数据。

    CloudEvents 可以为处理跨平台和跨服务的事件的消费者提供单一体验。

  • 促进跨服务和平台的集成

    事件数据跨环境传输的情况越来越普遍。然而,如果没有一种通用的描述事件的方式,事件的跨环境传输就会受到阻碍。没有单一的方法来确定事件的来源和可能的去向。这就阻碍了促进事件成功交付的工具化,也阻碍了消费者知道如何处理事件数据。

    CloudEvents 提供了有用的元数据,中间件和消费者可以依赖这些元数据来促进事件的路由、记录、传递和接收。

  • 提高FaaS的可移植性

    FaaS(也称无服务器计算)是IT领域发展最快的趋势之一,它主要是由事件驱动的。然而,FaaS的一个主要问题是供应商的锁定问题。这种锁定部分是由各供应商之间的函数API和签名的差异造成的,但这种锁定也是由函数内部接收事件数据的格式差异造成的。

    CloudEvents 对事件数据的通用描述方式提高了FaaS的可移植性。

  • 改进事件驱动/无服务器架构的开发和测试工作

    由于缺乏通用的事件格式,使得事件驱动和无服务器架构的开发和测试变得复杂化。没有简单的方法可以准确地模拟事件用于开发和测试,并帮助在开发环境中模拟事件驱动的工作流程。

    CloudEvents可以使开发人员有更好的工具来构建、测试和处理事件驱动和无服务器架构的端到端生命周期。

  • 事件数据演变

    大多数平台和服务对其事件的数据模型进行了不同的版本(如果他们根本不这么做的话)。这为发布和消费事件的数据模型创造了不一致的体验,因为这些数据模型在不断发展。

    CloudEvents 可以提供一种通用的方式来版本化和演进事件数据。这将帮助事件发布者根据最佳实践安全地对其数据模型进行版本化,这将帮助事件消费者在事件数据演进过程中安全地使用事件数据。

  • 规范化Webhooks

    Webhooks是一种没有使用通用格式的事件发布方式。Webhooks 的消费者没有一致的方式来开发、测试、识别、验证和整体处理通过 Webhooks 传递的事件数据。

    CloudEvents 可以为 webhook 发布和消费提供一致性。

  • 政策执行

    处于安全和策略的考虑,系统之间的事件的传送可能需要过滤、转换或阻止。例如,为了防止事件的进入或流出,如事件数据包含敏感信息或希望禁止发送方和接收方之间的信息流。

    一个通用的事件格式将使人们更容易推理正在流转的数据,并允许对数据进行更好的反省。

  • 事件追踪

    从源发送的事件可能会导致从各种中间件设备(如事件代理和网关)发送的附加事件序列。CloudEvents 包含事件中的元数据,可将这些事件作为事件序列的一部分进行关联,以进行事件追踪和故障排除。

  • IoT / 物联网

    物联网设备会发送和接收与其函数相关的事件。例如,一个连接的恒温器将发送关于当前温度的遥测数据,并可以接收改变温度的事件。这些设备通常有一个受限制的操作环境(CPU、内存),需要一个定义良好的事件消息格式。在很多情况下,这些消息是二进制编码的,而不是文本的。无论是直接来自设备还是通过网关转换,CloudEvents 都可以更好地描述消息的来源和消息中包含的数据格式。

  • 事件的关联性

    一个无服务器的应用程序/工作流可以与来自不同事件源/生产者的多个事件相关联。例如,一个防盗侦测应用/工作流可能同时涉及一个运动事件和一个门窗打开事件。一个无服务器平台可以接收到许多不同类型事件的实例,例如,它可以接收来自不同房屋的运动事件和门窗打开事件。

    无服务器平台需要将一种类型的事件实例与其他类型的事件实例正确关联,并将接收到的事件实例映射到正确的应用/工作流实例。CloudEvents 将为任何事件消费者(如无服务器平台)提供一种标准的方法,以便在事件数据中找到事件关联信息/标记,并将接收到的事件实例映射到正确的应用/工作流实例。

现有的事件格式

与上一节一样,对世界现状的审查(和了解)对小组来说非常重要。为此,我们收集了目前实践中使用的现有事件格式的样本。

具体格式内容见原文

3.1.4 - 核心规范

CloudEvents核心规范

备注:内容来自 https://github.com/cloudevents/spec/blob/v1.0/spec.md

摘要

CloudEvents 是一个厂商中立的规范,用于定义事件数据的格式。

概述

事件无处不在。然而,事件生产者往往会以不同的方式来描述事件。

缺乏描述事件的常用方法意味着开发人员必须不断重新学习如何接收事件。这也限制了库,工具和基础设施的可能性,以帮助跨环境(如SDK,事件路由器或跟踪系统)发送事件数据。我们可以从事件数据中实现的可移植性和生产力总体上受到阻碍。

CloudEvents 是一种用通用格式描述事件数据的规范,以提供跨服务、平台和系统的互操作性。

事件格式指定了如何用特定的编码格式对 CloudEvents 进行序列化。支持这些编码的 CloudEvents 实现必须遵守相应事件格式中指定的编码规则。所有实现都必须支持 JSON 格式

设计目标

这一段应该是搬到prier里面去了

CloudEvents通常用于分布式系统,以允许服务在开发期间松散耦合,独立部署,以后可以连接以创建新应用程序。

CloudEvents规范的目标是定义事件系统的互操作性,这些事件系统允许服务生成或消费事件,其中生产者和消费者可以独立开发和部署。生产者可以在消费者收听之前生成事件,并且消费者可以表达对尚未生成的事件或事件类别的兴趣。

为此,规范将包括促进互操作性的事件的公共元数据属性,而事件不包含可能用于发送事件的消费者或传输的任何细节。

非目标

以下内容不在规范中:

  • 函数构建和调用过程
  • 特定于语言的运行时API
  • 选择单一身份/访问控制系统

使用场景

下面的列表列举了为开发此规范而考虑的关键使用场景和开发人员视角。这些使用场景并非详尽无遗,并且该规范并非旨在规定如何使用。

这些情景不是规范性的; 任何人都可以自由地创建一个混合这些场景的系统。 这些案例建立了事件生成器,消费者,中间件和框架的通用词汇表。

在这些场景中,我们将事件生成器和事件使用者的角色保持不同。 单个应用程序上下文始终可以同时承担多个角色,包括既是事件生产者又是事件消费者。

  1. 应用程序生成供其他方使用的事件,例如为消费者提供有关终端用户活动,状态更改或环境观察的见解,或允许通过事件驱动的扩展来补充应用程序的功能。

    通常生成与上下文或生产者选择的分类相关的事件。例如,房间中的温度传感器可能由安装位置,房间,楼层和建筑物进行上下文限定。运动会结果可能按联赛和球队分类。

    生产者应用程序可以在任何地方运行,例如在服务器或设备上运行。

    生产的事件可以由生产者或中间人直接呈现和发布; 作为后者的示例,考虑由设备在诸如LoRaWAN或ModBus之类的有效载荷大小约束的网络上发送的事件数据,并且其中符合该规范的事件将由网络网关代表生产者呈现。

    例如,气象站通过LoRaWAN每5分钟发送一个12字节的专有事件有效载荷,指示天气状况。 然后使用LoRaWAN网关以CloudEvents格式将事件发布到Internet目标。LoRaWAN网关是事件生产者,代表气象站发布,并将适当地设置事件元数据以反映事件的来源。

  2. 应用程序将事件用于显示,归档,分析,工作流程处理,监视条件和/或为业务解决方案及其基础构建块的操作提供透明度等目的。

    消费者应用程序可以在任何地方运行,例如在服务器或设备上运行。

    消费事件的应用程序通常会对以下内容感兴趣:

    • 区分事件,使得完全相同的事件不会被处理两次。
    • 识别和选择原始上下文或生产者指定的分类。
    • 识别事件相对于始发上下文和/或相对于挂钟的时间顺序。
    • 理解事件中携带的与上下文相关的详细信息。
    • 关联来自多个事件生成器的事件实例,并将它们发送到相同的使用者上下文。

    在某些情况下,消费应用程序可能对以下内容感兴趣:

    • 从原始上下文获取有关事件主题的更多详细信息,例如获取有关需要特别访问授权的已更改对象的详细信息。例如,HR解决方案可能出于隐私原因在事件中仅发布非常有限的信息,并且任何需要更多数据的事件消费者将必须用他们自己的授权上下文中从HR系统获得与事件相关的细节。
    • 在原始上下文中与事件的主题交互,例如在被告知刚刚创建了该blob之后读取存储blob。

    消费者的兴趣所在会激励生产者在事件中包含哪些信息。

  3. 中间件将事件从生产者路由到消费者,或者转发到其他中间件。生成事件的应用程序可能会将因消费者需求而产生的某些任务委托给中间件:

    • 针对多个类别之一或原始事件上下文,管理许多并发感兴趣的消费者
    • 代表消费者根据事件的类别或原始上下文处理过滤条件。
    • 转码,如从JSON解码后编码为MsgPack
    • 改变事件结构的转换,例如从专有格式到CloudEvents的映射,同时保留事件的身份和语义完整性。
    • 即时“推送式”发送给感兴趣的消费者。
    • 存储最终交付的事件,由消费者的(“pull”),或者在延迟之后由中间件的(“push”)发起提取。
    • 监视事件内容或事件流以进行监视或诊断。

    为了满足这些需求,中间件将对以下内容感兴趣:

    • 可用于事件的分类或上下文化的元数据鉴别器,使得消费者可以表达对一个或多个这样的类或上下文的兴趣。例如,消费者可能对与文件存储帐户内的特定目录相关的所有事件感兴趣。
    • 元数据鉴别器,允许区分该类型或上下文的特定事件的主题。例如,消费者可能想要过滤掉与以“.jpg”结尾的新文件相关的所有事件(文件名是"新文件"事件的主题),用于描述它已经注册为感兴趣的文件存储帐户内的特定目录的上下文。
    • 用于编码事件及其数据的指示符。
    • 事件及其数据的结构布局(模式)的指示符。

    生产者的事件是否可通过中间件消费,是生产者的委托选择。

    在实践中,中间件可以在改变事件的语义含义时承担生成器的角色,在基于事件采取行动时承担消费者的角色,或在路由事件不进行语义更改时承担中间件的角色。

  4. 框架和其他抽象使得与事件平台基础设施的交互更简单,并且通常为多个事件平台基础设施提供通用API区域。

    • 框架通常用于将事件转换为对象图,并将事件分派给某些特定的用户代码处理或用户规则,以允许使用应用程序对原始上下文和特定主题中的特定类型的事件作出反应。

    • 框架最感兴趣的是它们抽象的平台上的语义元数据共性,因此可以统一处理类似的活动。

    对于体育应用程序,使用该框架的开发人员可能对来自联盟中的球队(感兴趣的topic)的今天的游戏(subject)的所有事件感兴趣,但是想要处理与“substitution”的报告不同的“goal”的报告。为此,框架将需要一个合适的元数据鉴别器,使其不必理解事件细节。

符号和术语

符号约定

本文档中的关键词 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, 和 “OPTIONAL” 按照 RFC 2119 中的描述进行解释。

为了清楚起见,当一个功能被标记为 “可选/OPTIONAL “时,这意味着消息的生产者和消费者都可以选择支持该功能。换句话说,如果生产者愿意,可以选择将该功能包含在消息中,如果消费者愿意,可以选择支持该功能。那么不支持该功能的消费者就会默默地忽略消息中的那部分内容。生产者需要为消费者忽略该功能的情况做好准备。中间人应该转发选择性属性。

术语

该规范定义了以下术语:

Occurrence/发生

“发生/occurrence"是指在软件系统运行过程中捕捉到的事实陈述。这可能是由于系统引发的信号或系统观察到的信号、状态变化、计时器过期或任何其他值得注意的活动而发生。例如,设备可能因为电池电量不足而进入警报状态,或者虚拟机即将执行预定的重启。

Event/事件

“事件/event"是表示发生(occurrence)及其上下文的数据记录。事件被从事件生产者(源)路由到感兴趣的事件消费者。可以根据事件中包含的信息进行路由,但事件不会确定具体的路由目的地。事件将包含两类信息:事件数据(Event Data)代表发生(occurrence),而上下文元数据(Context metadata)提供关于发生(occurrence)的上下文信息。一个发生(occurrence)可能会产生多个事件。

Producer/生产者

“Producer/生产者”是特定实例、过程或设备,用于创建描述 CloudEvent 的数据结构。

Source/来源

“Source/来源”是指发生(occurrence)出现的上下文。在一个分布式系统中,它可能由多个Producer组成。如果一个源不知道CloudEvents,外部生产者代表源创建CloudEvents。

Consumer/消费者

“Consumer/消费者"接收到事件,并对其采取行动。它使用上下文和数据来执行一些逻辑,这可能导致新事件的发生。

中介机构

“中介机构/Intermediary”接收包含事件的消息,目的是将其转发给下一个接收者,而这个接收者可能是另一个中间人或消费者。中间人的一个典型任务是根据上下文中的信息将事件转发到接收者。

Context/上下文

上下文元数据将被封装在上下文属性(Context Attributes)中。工具和应用程序代码可以使用这些信息来识别事件与系统的各个方面或与其他事件的关系。

数据

有关事件(即payload/有效载荷)的特定领域信息。这可能包括有关发生(occurrence)的信息、有关被更改的数据的详细信息或更多信息。有关更多信息,请参阅事件数据(Event Data)部分。

事件格式 / Event Format

事件格式指定了如何将 CloudEvent 序列化为字节序列。独立的事件格式(如 JSON 格式)可指定独立于任何协议或存储介质的序列化。协议绑定可以定义依赖于协议的格式。

Message/消息

事件通过消息从源(Source)传输到目的地(Destination)。

“结构化模式报文/structured-mode message” 是指使用独立的事件格式对事件进行完全编码并存储在消息主体中。

“二进制模式报文/binary-mode message” 是指事件数据(event data)存储在消息体中,事件属性作为消息元数据的一部分存储。

Data/数据

关于发生/occurrence(如有效载荷)的领域特定信息。这可能包括有关发生的信息,有关已更改数据的详细信息或更多。

Protocol/协议

消息可以通过各种行业标准协议(例如HTTP,AMQP,MQTT,SMTP),开源协议(例如Kafka,NATS)或平台/供应商特定协议(AWS Kinesis,Azure Event Grid)来传递。

Protocol Binding/协议绑定

协议绑定描述了事件如何通过给定协议发送和接收事件,特别是事件如何映射到该协议中的消息。

上下文属性

符合本规范的每个 CloudEvent 必须包含上下文属性,而且要指定为 REQUIRED,可以包含一个或多个 OPTIONAL 上下文属性,也可以包含一个或多个扩展属性。

这些属性在描述事件的同时,被设计为可以 独立于事件数据进行序列化。这使得它们可以在目的地被检查,而不需要对事件数据进行反序列化。

属性命名约定

CloudEvents 规范定义了对各种协议和编码的映射,随附的 CloudEvents SDK 针对各种运行时和语言。其中有些将元数据元素视为大小写敏感,而另一些则不敏感,而且单个 CloudEvents 可能会通过多个跳转来实现,中间涉及协议、编码和运行时。因此,本规范限制了所有属性的可用字符集,以防止大小写敏感问题或与通用语言中标识符的允许字符集冲突。

CloudEvents 属性名称必须由 ASCII 字符集中的小写字母(‘a’至’z’)或数字(‘0’至'9’)组成。属性名称应具有描述性和简洁性,长度不得超过 20 个字符。

类型系统

以下是可用于属性中的抽象数据类型。这些类型中的每个类型都可以由不同的事件格式和协议元数据字段来表示。本规范为每个类型定义了一个标准的字符串编码,所有的实现都必须支持。

  • Boolean - 值为 “true “或 “false “的布尔值。

    • 字符串编码:大小写敏感的 “true “或 “false” 值。
  • Integer -2,147,483,648到+2,147,483,647之间的整数。这是一个有符号的、32位的、二进制编码的范围。事件格式不一定要使用这个编码,但它们必须只使用这个范围内的整数值。

    • 字符串编码: 根据RFC 7159,第6节,JSON号码的整数部分。
  • String - 允许的Unicode字符序列。以下字符不允许使用。

    • U+0000-U+001F 和 U+007F-U+009F (两个范围都包括在内)中的 “控制字符”,因为大多数字符没有约定的含义,有些字符,如 U+000A (换行符),在HTTP 头等上下文中不能使用。

    • 代码点被Unicode识别为非字符。

    • U+D800-U+DBFF和U+DC00-U+DFFF,这两个范围都包括在内,除非正确地成对使用。因此,(在JSON符号中)"\uDEAD “是无效的,因为它是一个未配对的代名词,而”\uD800\uDEAD “是合法的。

  • Binary - 字节序列。

    • 字符串编码: Base64 编码,按照 RFC4648 的规定进行编码。
  • URI–绝对统一的资源标识符。

    • 字符串编码:RFC4648中定义的绝对统一资源标识符。字符串编码:RFC 3986 第 4.3 节中定义的绝对 URI。
  • URI-reference - 统一资源标识符引用。

    • 字符串编码:RFC 3986 第4.3 节中定义的URI-reference。URI-reference - RFC 3986 第4.1 节中定义的URI-reference。
  • Timestamp - 使用Gregorian Calendar的日期和时间表达式。

    • 字符串编码:RFC 3339。

所有的上下文属性值必须是上面列出的类型之一。属性值可以以本地类型或标准字符串的形式呈现。

表示 CloudEvent 或任何扩展的强类型编程模型必须能够将常规字符串编码转换为最适合抽象类型的运行时/语言原生类型。

例如,在给定的实现中,时间属性可以用语言的本机日期时间类型来表示,但必须提供 RFC3339 字符串,并且在映射到 HTTP 消息的报文头时,必须可转换为 RFC3339 字符串。

同样,CloudEvents 协议绑定或事件格式实现也必须能够在编码或协议元数据字段中将标准字符串编码转换为相应的数据类型。

时间戳类型的属性值确实可以作为一个字符串通过多次跳转,并且只在生产者和最终消费者那里以本地运行时/语言类型的形式实现。时间戳也可能被路由为本地协议类型,并可能在生产者和消费者端被映射到/从各自的语言/运行时类型,而永远不会以字符串的形式实现。

序列化机制的选择将决定上下文属性和事件数据的序列化方式。例如,在JSON序列化的情况下,上下文属性和事件数据可能同时出现在同一个JSON对象中。

必须的属性

以下属性必须在所有 CloudEvents 中出现。

id

  • Type: String
  • 描述: 标示事件。生产者必须确保 source + id 对于每个独立的事件都是唯一的。如果一个重复的事件被重新发送(例如,由于网络错误),它可能有相同的id。消费者可能会认为 source 和 id 相同的事件是重复的。
  • Examples:
    • 由生产者维护的事件计数器
    • UUID
  • Constraints:
    • REQUIRED
    • 必须是一个非空字符串
    • 必须在生产者范围内是唯一的

source

  • Type: URI-reference

  • Description: 标示事件发生的上下文。通常包括事件源的类型、发布事件的组织或产生事件的过程等信息。URI 中编码的数据背后的确切语法和语义由事件生产者定义。

    生产者必须确保 source + id 对于每个独立的事件都是唯一的。

    应用程序可以为每个独立的生产者分配一个唯一的source,这样就很容易产生唯一的ID,因为没有其他生产者会有相同的source。应用程序可以使用 UUIDs、URNs、DNS 权限或特定于应用程序的方案来创建唯一的source标识符。

    一个源也可以包括多个的生产者。在这种情况下,生产者必须合作,确保 source + id 对于每个独立的事件都是唯一的。

  • Constraints:

    • REQUIRED
    • MUST be a non-empty URI-reference
    • 推荐使用绝对URI
  • Examples

specversion

  • Type: String
  • Description: 事件所使用的 CloudEvents 规范的版本。该版本可用于解释上下文。兼容的事件制作者在引用此版本的规范时,必须使用 1.0 的值。
  • Constraints:
    • REQUIRED
    • MUST be a non-empty string

type

  • Type: String
  • Description: 该属性包含一个描述事件类型的值,描述与起源事件相关的事件类型。该属性通常用于路由、可观察性、策略执行等。该属性的格式是由生产者定义的,可能包括类型的版本等信息–更多信息请参见Primer中的属性版本化。
  • Constraints:
    • REQUIRED
    • MUST be a non-empty string
    • 应该以一个反转的DNS名称为前缀。前缀域决定了定义这个事件类型的语义的组织。
  • Examples
    • com.github.pull.create
    • com.example.object.delete.v2

可选属性

以下为可在 CloudEvents 中出现的可选属性。有关 OPTIONAL 定义的更多信息,请参阅 Notational Conventions 部分。

datacontenttype

  • Type: String per RFC 2046

  • Description: data 值的内容类型。该属性使数据可以携带任何类型的内容,其格式和编码可能与所选事件格式不同。例如,使用JSON信封格式渲染的事件可能会携带一个XML有效载荷的数据,这个属性被设置为 “application/xml “就会通知消费者。不同的数据内容如何渲染不同的数据内容类型值的规则在事件格式规范中定义了;例如,JSON事件格式在3.1节中定义了这种关系。

    对于一些二进制模式的协议绑定,该字段直接映射到各自协议的内容类型元数据属性。二进制模式和内容类型元数据映射的规范性规则可以在相应的协议中找到。

    在某些事件格式中,datacontententtype属性可能会被省略。例如,如果一个JSON格式的事件没有datacontententtype属性,那么就意味着数据是符合 “application/json “媒体类型的JSON值。换句话说:一个没有datacontententtype的JSON格式事件与一个datacontenttype=“application/json “的事件完全等同。

    当将一个没有datacontenttype属性的事件消息翻译成不同的格式或协议绑定时,目标datacontenttype应该明确地设置为源的隐含datacontenttype。

  • Constraints:

    • OPTIONAL
    • 如果存在,必须遵守RFC 2046中规定的格式。
  • For Media Type examples see IANA Media Types

dataschema

  • Type: URI
  • 指明 data 所遵循的 schema。对模式的不兼容的更改应该通过不同的URI来反映。更多信息请参见Primer中的属性版本化。
  • Constraints:
    • OPTIONAL
    • If present, MUST be a non-empty URI

subject

  • Type: String

  • Description: 描述了事件生产者(通过 source 标识)上下文中的事件主题。在发布-订阅场景中,订阅者通常会订阅由源发出的事件,但如果源上下文有内部子结构,仅有源标识符可能不足以作为任何特定事件的限定符。

    在上下文元数据中识别事件的主体(而不是仅在 data 有效载荷中),这在中间件无法解释 data 内容的通用订阅过滤场景中特别有帮助。在上面的例子中,订阅者可能只对以'.jpg’或'.jpeg’结尾的blob感兴趣,而主题属性允许为该事件的子集构造一个简单有效的字符串后缀过滤器。

  • Constraints:

    • OPTIONAL
    • If present, MUST be a non-empty string
  • Example:

    • 当在blob-存储容器内创建新的blob时,订阅者可能会注册兴趣。在这种情况下,事件 source 标识了订阅范围(存储容器),type 标识了 “blob创建 “事件,id唯一标识了事件实例,以区分已创建的相同名称的blob的单独出现;新创建的blob的名称在 subject中携带。
      • source:https://example.com/storage/tenant/container
      • subject: mynewfile.jpg

time

  • Type: Timestamp
  • Description: 事件发生的时间戳。如果无法确定事件发生的时间,则该属性可以由 CloudEvents 生产者设置为其他时间(如当前时间),但同一源的所有生产者在这方面必须保持一致。换句话说,它们要么都使用实际发生的时间,要么都使用相同的算法来确定所使用的值。
  • Constraints:
    • OPTIONAL
    • If present, MUST adhere to the format specified in RFC 3339

扩展上下文属性

CloudEvent 可包含任意数量的具有不同名称的附加上下文属性,称为 “扩展属性”。扩展属性必须遵循与标准属性相同的命名惯例,并使用与标准属性相同的类型系统。扩展属性在本规范中没有定义的含义,它们允许外部系统将元数据附加到事件中,就像HTTP自定义头一样。

扩展属性总是按照与标准属性一样的绑定规则进行序列化。然而,本规范并不妨碍扩展将事件属性值复制到消息的其他部分,以便与同样处理消息的非CloudEvents系统进行交互。这样做的扩展规范应该指定如果复制的值与 cloud event 序列化的值不同,接收者应该如何解释消息。

定义扩展

请参阅 CloudEvent 属性扩展,了解有关扩展的使用和定义的更多信息。

扩展的定义应该完全定义属性的所有方面,例如,其名称、类型、语义和可能的值。新的扩展定义应该使用一个描述性足够强的名称,以减少与其他扩展名称碰撞的可能性。特别是,扩展作者应该检查文档中的扩展文档中的已知扩展集–不仅仅是检查可能的名称冲突,还应该检查可能感兴趣的扩展。

许多协议支持发送者包含附加元数据的能力,例如作为 HTTP 头文件。虽然 CloudEvents 接收方没有被强制要求处理和传递这些元数据,但建议他们通过某种机制来处理和传递这些元数据,以表明它们是非 CloudEvents 元数据。

下面是一个例子,说明了对附加属性的需求。在许多 IoT 和企业用例中,一个事件可以在无服务器的应用程序中使用,该事件可以在多个类型的事件中执行操作。为了支持这样的用例,事件生产者需要在 “上下文属性 “中添加额外的身份属性,事件消费者可以使用这些属性将该事件与其他事件关联起来。如果这种身份属性恰好是事件 “数据 “的一部分,事件生产者也将把身份属性添加到 “上下文属性 “中,这样,事件消费者就可以方便地访问这些信息,而不需要解码和检查事件数据。这样的身份属性也可以用来帮助中间网关确定如何路由事件。

事件数据

正如术语 “Data “所定义的那样,CloudEvents 可包括与事件发生相关的领域特定信息。如果存在,此信息将被封装在 data 中。

  • 描述:事件有效载荷(Payload)。本规范不对该信息的类型进行任何限制。它被编码成由datacontententtype属性指定的媒体格式(例如:application/json),并且当这些相应的属性存在时,它将遵循dataschema格式。
  • Constraints:
    • OPTIONAL

大小限制

在许多场景中,CloudEvents 将通过一个或多个通用中间人转发,每个中间人都可能会对转发事件的大小进行限制。CloudEvents 也可能会被转发到消费者,比如嵌入式设备,这些设备受存储或内存限制,因此在处理大的单一事件时可能会很吃力。

事件的 “大小"是指事件的线上(wire-size)大小,包括事件的线上传输的每一个比特:协议帧元数据、事件元数据和事件数据,基于所选的事件格式和所选的协议绑定。

如果应用配置要求在不同的协议之间转发事件,或要求对事件进行重新编码,则应考虑应用所使用的最有效的协议和编码,以符合这些大小限制。

  • 中间商必须转发大小为64KByte或以下的事件。
  • 消费者应接受至少64 KByte大小的事件。

实际上,这些规则将允许生产者安全地发布大小不超过64KB的事件。这里的 “安全 “指的是,一般来说,期望事件被所有中间人接受并转发是合理的。出于本地的考虑,它是否愿意接受或拒绝该大小的事件,是在任何特定消费者的控制范围内。

一般来说,CloudEvents 发布者应该通过避免在事件有效载荷中嵌入大型数据项来保持事件的紧凑性,而是使用事件有效载荷链接到这些数据项。从访问控制的角度来看,这种方法还可以让事件的分布范围更广,因为通过解析链接访问事件相关的细节,可以实现差异化的访问控制和选择性的披露,而不是直接将敏感细节嵌入事件中。

隐私和安全

互操作性是本规范背后的主要驱动力,要实现这样的行为,需要将一些信息公开,导致信息泄露的可能性。

请考虑以下几点,以防止不经意间的泄漏,特别是在利用第三方平台和通信网络时。

  • 上下文属性

    敏感信息不应在上下文属性中携带或表示。

    CloudEvent 生产者、消费者和中间人可以审查并记录上下文属性。

  • Data

    领域特定 event data 应进行加密,以限制受信任方的可见性。用于这种加密的机制是生产者和消费者之间的协议,因此不属于本规范的范围。

  • Protocol Bindings

    应采用协议级的安全性,以确保CloudEvents的可信和安全交换。

示例

下面的示例展示了一个被序列化为JSON的CloudEvent:

{
    "specversion" : "1.0",
    "type" : "com.github.pull.create",
    "source" : "https://github.com/cloudevents/spec/pull",
    "subject" : "123",
    "id" : "A234-1234-1234",
    "time" : "2018-04-05T17:31:00Z",
    "comexampleextension1" : "value",
    "comexampleothervalue" : 5,
    "datacontenttype" : "text/xml",
    "data" : "<much wow=\"xml\"/>"
}

3.1.5 - HTTP Protocol Binding

CloudEvents规范中的HTTP Protocol Binding

备注:内容来自 https://github.com/cloudevents/spec/blob/v1.0/http-protocol-binding.md

摘要

CloudEvents 的 HTTP 协议绑定定义了如何将事件映射到 HTTP 1.1 请求和响应消息。

1. 简介

CloudEvents是事件的结构和元数据描述的标准化且与协议无关的定义。该规范定义了如何在HTTP 1.1请求和响应消息中使用CloudEvents规范中定义的元素。

1.1 Conformance

本文档中的关键词 “MUST”、“MUST NOT”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、“MAY “和 “OPTIONAL “等,应按RFC2119中的解释。

1.2 与 HTTP 的关系

本规范没有规定约束特定HTTP方法的使用或处理规则,也没有约束用于传输或请求事件的HTTP目标资源。

事件可以通过所有支持有效载荷体传输的标准或应用程序定义的HTTP请求方法来传输。事件也可以在HTTP响应中以及与允许有效载荷体传输的所有HTTP状态码一起传输。

这里所有显示HTTP方法、HTTP目标URI和HTTP状态码的例子都是非规范性的说明。

本规范也同样适用于与 HTTP 1.1语义兼容的 HTTP/2(RFC7540)。

注意:也适用于HTTP/2

1.3 内容模式

本规范定义了传输事件的三种内容模式:二进制(binary)、结构化(structured)和批量(batched)。每个符合规范的实现都应该支持二进制(binary)和结构化(structured)模式。

在二进制内容模式下,事件 data 的值被放置到HTTP请求或响应的主体(body)中,并在HTTP Content-Type header中以 datacontenttype属性的值声明其媒体类型;所有其他事件属性都被映射到HTTP头。

在结构化内容模式下,事件元数据属性和事件数据被放置到HTTP请求或响应body中,使用事件格式。

在批量内容模式中,多个事件使用支持批量的事件格式,分批放入单个HTTP请求或响应body中。

1.4 事件格式

与结构化内容模式一起使用的事件格式,定义了事件如何以特定的数据格式表达。本规范的所有实现必须支持非批处理的JSON事件格式,但也可以支持任何其他格式,包括专有格式。

事件格式可以额外定义事件批处理的表达方式。这些格式可以与批处理内容模式一起使用。

1.5 安全

本规范没有为HTTP引入任何新的安全特性,也没有规定要使用特定的现有特性。本规范同样适用于TLS上的HTTP。

2. CloudEvents 属性的使用

本规范没有进一步定义任何核心 CloudEvents 事件属性。

此映射是为了防止变化(包括事件属性的添加和删除),并适应供应商对事件元数据的扩展。

2.1 datacontententtype 属性

datacontententtype属性被认为包含一个符合RFC2046的媒体类型表达式。

2.2 data

data 被假定为包含由 datacontenttype 属性声明的不透明的应用数据。

应用程序可以自由地以其选择的任何内存中的表示方式来保存信息,但是由于该值是按照本规范中的定义被转接到HTTP中的,因此假设 data 的值是以字节序列的形式提供的。

例如,如果声明的 datacontenttype 为 application/json;charset=utf-8,则期望 data 值以 UTF-8 编码的JSON文本形式提供给HTTP。

3. HTTP消息映射

HTTP请求和响应消息的事件绑定是相同的。

内容模式是由事件的发送方选择的,发送方可以是请求方或响应方。可能允许使用特定模式请求事件的手势可能是由应用程序定义的,但这里没有定义。除非被邀约,否则不能使用批量模式,而且手势应该允许接收方选择最大的批处理量。

事件的接收方可以通过检查 Content-Type header 的值来区分这三种模式。如果该值前缀为 CloudEvents 媒体类型 application/cloudevents,表示使用已知的事件格式,则接收方使用结构化模式。如果该值前缀为 application/cloudevents-batch,则接收器使用批处理模式。否则,则默认为二进制模式。

备注:默认是使用二进制模式

如果接收器检测到 CloudEvents 媒体类型,但它无法处理的事件格式(例如 application/cloudevents+avro),它仍然可以将事件作为二进制模式处理,并将其转发到另一方。

3.1. 二进制内容模式

二进制的内容模式可以容纳任何形状的事件数据,并允许高效传输,无需转码。

3.1.1. HTTP Content Type

对于二进制模式,HTTP Content-Type header值对应于(必须从 CloudEvents datacontenttype 属性中填充或写入)CloudEvents datacontenttype 属性。请注意 ce-datacontenttype HTTP 标头不能也存在于消息中。

3.1.2. 事件数据编码

data 字节序列作为HTTP报文Body。

3.1.3. Metadata headers

所有其他 CloudEvents 属性(包括扩展)必须单独映射到不同的 HTTP 消息头,并从不同的 HTTP 消息头中映射。

定义了自己属性的 CloudEvents 扩展可以为这些属性定义二级映射到 HTTP 头,特别是当特定属性需要与 HTTP 特性或其他有明确 HTTP 头绑定的规范保持一致时。请注意,这些属性还必须作为带有 ce 前缀的 HTTP 标头出现在 HTTP 报文中,如 HTTP 标头名称中所述。

3.1.3.1. HTTP Header Names

除注明的情况外,所有 CloudEvents 上下文属性(包括扩展)都必须映射到与属性名称相同但前缀为 ce 的 HTTP header中。

Examples:

* `time` maps to `ce-time`
* `id` maps to `ce-id`
* `specversion` maps to `ce-specversion`

注意:根据HTTP规范,header name是不区分大小写的。

3.1.3.2. HTTP header值

每个 HTTP header的值由相应属性类型的标准字符串表示法构建。

某些 CloudEvents 元数据属性可包含任意 UTF-8 字符串内容,根据 RFC7230 第 3 节,HTTP 标头必须仅使用 US-ASCII 字符集中的可打印字符,并由 CRLF 序列终止,标头值周围有可选的空白。

在应用[RFC7230,第3.2.6节][RFC7230-3-2s6]中描述的 header 编码规则之前,必须按照RFC3986,第2.4节中描述的百分比编码,对字符串值进行百分比编码。

将 HTTP 报文解码为 CloudEvent 时,必须反向应用这些规则 – RFC7230 第 3.2.6 节对 ASCII 字符串进行解码,然后按照 RFC3986 第 2.4 节中的描述进行单轮百分比解码,以生成有效的 UTF-8 字符串。(注意,应用百分比解码的次数不正确可能导致报文损坏或安全问题)。

3.1.4. Examples

这个例子显示了带有HTTP POST请求的事件与的二进制模式映射:

POST /someresource HTTP/1.1
Host: webhook.example.com
ce-specversion: 1.0
ce-type: com.example.someevent
ce-time: 2018-04-05T03:56:24Z
ce-id: 1234-1234-1234
ce-source: /mycontext/subcontext
    .... further attributes ...
Content-Type: application/json; charset=utf-8
Content-Length: nnnn

{
    ... application data ...
}

这个例子显示了包含事件的响应:

HTTP/1.1 200 OK
ce-specversion: 1.0
ce-type: com.example.someevent
ce-time: 2018-04-05T03:56:24Z
ce-id: 1234-1234-1234
ce-source: /mycontext/subcontext
    .... further attributes ...
Content-Type: application/json; charset=utf-8
Content-Length: nnnn

{
    ... application data ...
}

3.2. 结构化内容模式

结构化的内容模式将事件元数据和数据保持在有效载荷中,使得同一事件可以在多个路由跳转、多协议之间简单转发。

3.2.1. HTTP内容类型

HTTP内容类型头必须设置为事件格式的媒体类型。

JSON 格式的示例。

Content-Type: application/cloudevents+json; charset=UTF-8

3.2.2. 事件数据编码

所选择的事件格式定义了所有属性和数据的表示方式。

然后按照事件格式规范对事件元数据和数据进行渲染,最后得到的数据成为HTTP报文body。

3.2.3. metadata header

实现可以包含与二进制模式定义的相同的 HTTP 标头。

所有 CloudEvents 元数据属性都必须映射到有效载荷(Payload)中,即使它们也已经映射到 HTTP header中了。

3.2.4. 示例

这个例子显示了一个JSON事件格式编码的事件,用PUT请求发送:

PUT /myresource HTTP/1.1
Host: webhook.example.com
Content-Type: application/cloudevents+json; charset=utf-8
Content-Length: nnnn

{
    "specversion" : "1.0",
    "type" : "com.example.someevent",

    ... further attributes omitted ...

    "data" : {
        ... application data ...
    }
}

这个例子显示了一个响应中返回的JSON编码的事件:

HTTP/1.1 200 OK
Content-Type: application/cloudevents+json; charset=utf-8
Content-Length: nnnn

{
    "specversion" : "1.0",
    "type" : "com.example.someevent",

    ... further attributes omitted ...

    "data" : {
        ... application data ...
    }
}

3.3. 批量内容模式

在批量内容模式下,多个事件被批量到一个HTTP请求或响应体中。选择的事件格式必须定义如何表示一个批次。基于JSON格式(任何兼容的实现都必须支持JSON格式),JSON Batch格式是一种支持批处理的事件格式。

3.3.1. HTTP 内容类型

HTTP Content-Type头必须设置为事件格式的媒体类型。

JSON Batch 格式的示例。

Content-Type: application/cloudevents-batch+json; charset=UTF-8

3.3.2. 事件数据编码

所选的事件格式定义了一批事件和所有事件属性和数据的表示方式。

然后根据事件格式规范对事件批进行渲染,结果数据将成为HTTP消息主体。

该批事件可以是空的。所有批处理的 CloudEvents 必须具有相同的 specversion 属性。其他属性可能不同,包括 datacontententtype 属性。

3.2.3 Examples

This example shows two batched CloudEvents, sent with a PUT request:

PUT /myresource HTTP/1.1
Host: webhook.example.com
Content-Type: application/cloudevents-batch+json; charset=utf-8
Content-Length: nnnn

[
    {
        "specversion" : "1.0",
        "type" : "com.example.someevent",

        ... further attributes omitted ...

        "data" : {
            ... application data ...
        }
    },
    {
        "specversion" : "1.0",
        "type" : "com.example.someotherevent",

        ... further attributes omitted ...

        "data" : {
            ... application data ...
        }
    }
]

This example shows two batched CloudEvents returned in a response:

HTTP/1.1 200 OK
Content-Type: application/cloudevents-batch+json; charset=utf-8
Content-Length: nnnn

[
    {
        "specversion" : "1.0",
        "type" : "com.example.someevent",

        ... further attributes omitted ...

        "data" : {
            ... application data ...
        }
    },
    {
        "specversion" : "1.0",
        "type" : "com.example.someotherevent",

        ... further attributes omitted ...

        "data" : {
            ... application data ...
        }
    }
]

3.1.6 - Json事件格式

CloudEvents规范中的HJson事件格式

备注:内容来自 https://github.com/cloudevents/spec/blob/v1.0/json-format.md

2. Attributes

本节定义了 CloudEvents 属性如何映射到 JSON。本规范没有明确映射每个属性,但提供了一个通用映射模型,该模型适用于所有当前和未来的 CloudEvents 属性(包括扩展)。

为明确起见,扩展属性使用与规范定义的属性相同的规则进行序列化。这包括其语法和在 JSON 对象中的位置。特别是,扩展作为顶层 JSON 属性放置。扩展必须被序列化为顶层JSON属性。这个设计决定有很多原因,在Primer中会详细介绍。

2.2. Type System Mapping

扩展规范可以为其定义的属性值定义二次映射规则,但必须包括之前定义的主映射。

例如,属性值可能是在 CloudEvents 以外的标准中定义的数据结构,具有正式的 JSON 映射,如果不保留原始格式,可能会有翻译错误或信息丢失的风险。

定义了 JSON 次要映射规则的扩展规范,以及对该规范的任何修订,都必须为提交或修订时属于 CloudEvents 核心的所有其他事件格式定义明确的映射规则。

如果需要,例如在解码地图时,CloudEvents 类型可以通过使用映射表中的规则进行推理来确定,其中唯一潜在的模糊 JSON 数据类型是字符串。当满足映射规则时,该值与相应的 CloudEvents 类型兼容。

3. Envelope

每个 CloudEvents 事件可以完全表示为一个 JSON 对象。

这种表示方式必须使用媒体类型 application/cloudevents+json。

给定事件中的所有 REQUIRED 和所有未省略的 OPTIONAL 属性必须成为 JSON 对象的成员,相应的 JSON 对象成员名称与属性名称相匹配,并且成员的类型和值使用类型系统映射。

3.1. 对 “data"的处理

在采取行动之前,JSON序列化器必须首先确定数据内容的运行时数据类型。

如果实现确定数据类型为二进制,则必须将值表示为包含Base64编码的二进制值的JSON字符串表达式,并使用成员名data_base64将其存储在JSON对象中。

对于任何其他类型,实现必须将数据值转换为JSON值,并使用成员名data_base64来存储在JSON对象中。

由此可见,在 JSON 序列化的 CloudEvent 中,数据和 data_base64 成员的使用是相互排斥的。

当从 JSON 中解串化 CloudEvents 时,data_base64 成员的存在清楚地表明该值是 Base64 编码的二进制数据,序列化器必须将其解码为二进制的运行时数据类型。当数据成员存在时,它将使用默认的JSON类型映射来解码,用于使用的运行时。

与属性不同的是,根据类型系统映射,值类型被限制为字符串,而产生的数据成员JSON值是不受限制的,可以包含任何有效的JSON。

3.1.7 - SDK需求

CloudEvents规范中的SDK需求

备注:内容来自 https://github.com/cloudevents/spec/blob/master/SDK.md

本文档的目的是描述针对CloudEvents的新软件开发工具包(SDK)的最低要求。这些SDK的设计和实施是为了增强和加快CloudEvents的集成。作为社区工作的一部分,CloudEvents团队承诺支持和维护以下SDK。

本文档旨在为 SDK 作者提供指导和要求。本文档旨在与 CloudEvents 规范保持同步更新。

技术需求

每个SDK必须满足这些要求。

  • 支持CloudEvents 的里程碑版本和正在进行的开发版本。
    • 将Canonical Event编码为特定于传输的编码消息。
    • 将特定于传输的编码消息解码为Canonical事件。
  • 熟练使用编程语言。
    • 使用当前的语言版本。
  • 支持结构化和二进制编码的HTTP传输渲染。

对象模型结构准则

每个SDK将提供一个通用的CloudEvents类/对象/结构,该类/对象/结构表示事件的典型形式。

该 SDK 应使用户能够绕过 CloudEvents Event 对象的特定传输编码和解码。对象的一般流程应该是:

Event (-> Message) -> Transport

Transport (-> Message) -> Event

不需要SDK来实现传输的包装器,重点应该是允许编程模型与高层次的Event对象一起工作,并提供工具将Event转化成可以与所选的实现传输一起使用的东西。

在高层次上,SDK需要能够帮助完成以下任务。

  • 组合事件。
  • 编码事件,给定传输和编码(如果适当的话,将其编码为传输消息)。
  • 解码特定于传输的消息、请求或响应(如果适当的话,到一个传输消息)为事件。

组合事件

提供一种方便的方法,既可以组成单一消息,也可以组成许多消息。实现者将需要一种方法来快速建立事件数据并将其转换为CloudEvents编码的事件。在实践中,事件的组成往往有两个方面。

  1. 事件创建

    “我有一个格式不是CloudEvent的数据,我想让它成为CloudEvent。”

  2. 事件变化

    “我有一个CloudEvents格式化的事件,我需要将它变成不同的事件。” “我有一个CloudEvents格式化的事件,我需要修改事件。”

对于SDK语言来说,事件的创建是非常习以为常的。

事件变化往往用访问器模式来解决,比如getters和setter。但是可以利用直接的 key 访问,也可以利用命名的 key 访问器函数。

无论是哪种情况,都必须有一个方法根据参数设置来验证生成的Event对象,最重要的是CloudEvents规范版本。

对事件进行编码/解码

每个SDK都支持对事件进行编码和解码。结构化编码是最容易支持的,因为它只是json,但二进制编码对于每个传输方式来说是相当定制的。

数据

从事件中访问数据有一些考虑,事件可以被编码成base64形式,作为结构化数据,或者像json这样的线上格式。一个SDK必须提供一种方法来将这些格式的数据解压成原生格式。

扩展

支持CloudEventss的扩展又是成语,但镜像数据访问的方法似乎是可行的。

验证

验证必须在单个事件上进行。验证必须考虑到规格版本,以及每个版本的规格所提出的所有要求。

文档

每个SDK必须提供至少使用HTTP传输的例子。

  • 组成事件。
  • 对组成的事件进行编码和发送。
  • 接收和解码事件。

4 - Serverless项目

serverless项目

4.1 - 概述

serverless项目概述

Functions-as-a-Service (FaaS)

将逻辑编写为响应各种事件的小块代码。

  • AWS Lambda
  • Azure Functions
  • 基于Apache OpenWhisk的IBM Cloud Functions
  • Google Cloud Functions
  • 华为Function Stage 和 Function Graph
  • Kubeless
  • iron.io
  • funktion
  • fission
  • nuclio

时间线

  • 虽然按需或“花多少用多少”模式的概念可追溯到2006年和一个名为Zimki的平台
  • serverless一词的第一次使用是2012年来自Iron.io的IronWorker产品 ,一个基于容器的分布式按需工作平台。

从那以后,公共云和私有云都出现了更多serverless实现:

在云服务厂商之外,开源社区也涌现出很多优秀的Serverless框架,比如

4.2 - AWS Lambda项目

AWS Lambda项目

4.2.1 - Lambda Layers

Lambda Layers

背景

AWS 在2018年11月推出两个新功能,声称将使无服务器开发变得更加容易:

  • Lambda Layers:用于集中管理跨功能共享的代码和数据
  • Lambda Runtime API,一个使用任何编程语言或特定语言版本的简单接口,用于开发函数,将 AWS Lambda 从 JavaScript 扩展到其他编程语言

这两个功能可以一起使用:Runtime可以作为Layer共享,以便开发人员可以在创建Lambda函数时选择它们并使用自己喜欢的编程语言。

Lambda Layers

Lambda Layers介绍

构建serverless应用程序时,通常会在Lambda函数之间共享代码。可以是由多个函数使用的自定义的代码,或者是用来简化业务逻辑实现的标准库。

以前,必须将此共享代码与所有使用它的函数一起打包和部署:

现在,您可以将常用组件放在ZIP文件中并将其作为Lambda Layer上传。您的函数代码不需要更改,并且可以像通常那样引用Layer中的库:

Layer可以帮助在函数间更方便的共享代码:Upload layer once,reference within any function!

而Layer可以包含任意内容,包括:依赖,数据,配置文件,实用工具等。

Layer的优点

使用Layer可以使部署包保持较小,从而使开发更容易。可以避免在函数代码安装和打包依赖时可能发生的错误。对于Node.js,Python和Ruby函数,在Lambda控制台中开发函数代码,可以将部署包保持在3 MB以下。

  • 实现关注点分离:分离业务逻辑和依赖
  • 使函数代码更小,更专注于想要构建的内容
  • 加快部署速度,因为必须打包和上载的代码更少了,并且可以重用依赖

Layer的使用方式

在函数的配置中,最多可以引用五个Layer,其中一个Layer可以选择是runtime。调用该函数时,将按照您提供的顺序在 /opt 中安装Layer。顺序很重要,因为Layer都是在同一路径下提取的,因此每个Layer都可能覆盖前一个Layer。这个方式可用于自定义环境。例如,第一个Layer可以是runtime,第二个Layer可以添加所需库的特定版本。

Layer可以在AWS账户内使用,在账户之间共享,也可以与开发人员社区公开共享。

使用Runtime和Layer无需额外费用。

使用方式:

$ aws lambda update-function-configuration --function-name my-function \
--layers arn:aws:lambda:us-east-2:123456789012:layer:my-layer:3 \
arn:aws:lambda:us-east-2:210987654321:layer:their-layer:2
{
    "FunctionName": "test-layers",
    "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function",
    "Runtime": "nodejs8.10",
    "Role": "arn:aws:iam::123456789012:role/service-role/lambda-role",
    "Handler": "index.handler",
    "CodeSize": 402,
    "Description": "",
    "Timeout": 5,
    "MemorySize": 128,
    "LastModified": "2018-11-14T22:47:04.542+0000",
    "CodeSha256": "kDHAEY62Ni3OovMwVO8tNvgbRoRa6IOOKqShm7bSWF4=",
    "Version": "$LATEST",
    "TracingConfig": {
        "Mode": "Active"
    },
    "RevisionId": "81cc64f5-5772-449a-b63e-12330476bcc4",
    "Layers": [
        {
            "Arn": "arn:aws:lambda:us-east-2:123456789012:layer:my-layer:3",
            "CodeSize": 169
        },
        {
            "Arn": "arn:aws:lambda:us-east-2:210987654321:layer:their-layer:2",
            "CodeSize": 169
        }
    ]
}

详见官方文档:

https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html

注意:必须通过提供Layer版本的完整ARN来指定要使用的每个图层的版本。

可以对Layer进行版本控制以管理多个更新,每个版本都是不可变的。删除版本或版本的使用权限被撤销时,之前使用它的函数将继续有效,但您将无法创建新的函数。

对Layer的使用权限管理

Layer的来源可以有多种:

  • 来自单个AWS账号
  • 在多个账号之间共享使用
  • 公开发布,社区共享,如AWS提供的Python类库Numpy和SciPy

可以通过设置Policy对Layer的使用进行权限管理,包括对Layer自身的管理。

下面的例子授权用户可以对名字以 test- 开头的Layer进行版本的Publish/Get/Detele操作:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublishLayers",
            "Effect": "Allow",
            "Action": [
                "lambda:PublishLayerVersion"
            ],
            "Resource": "arn:aws:lambda:*:*:layer:test-*"
        },
        {
            "Sid": "ManageLayerVersions",
            "Effect": "Allow",
            "Action": [
                "lambda:GetLayerVersion",
                "lambda:DeleteLayerVersion"
            ],
            "Resource": "arn:aws:lambda:*:*:layer:test-*:*"
        }
    ]
}

下面的Policy通过在函数的 create 和 updateFunctionConfiguration 操作中加入条件,限制为只能使用来自 account 123456789012 的Layer:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ConfigureFunctions",
            "Effect": "Allow",
            "Action": [
                "lambda:CreateFunction",
                "lambda:UpdateFunctionConfiguration"
            ],
            "Resource": "*",
            "Condition": {
                "ForAllValues:StringLike": {
                    "lambda:Layer": [
                        "arn:aws:lambda:*:123456789012:layer:*:*"
                    ]
                }
            }
        }
    ]
}

详情见:https://docs.aws.amazon.com/lambda/latest/dg/access-control-identity-based.html#permissions-user-layer

Lambda Runtime

Lambda Runtime介绍

虽然AWS Lambda目前已经支持多种语言和版本,但是还有非常多的语言或者语言版本不被支持,为此AWS推出了Lambda Runtime来实现自定义Runtime。

理论上,任何可以兼容Linux的语言都可以通过开发对应的 Lambda 自定义 Runtime 的方式来提供。

Lambda Runtime是一个程序,当调用 Lambda 函数时,Runtime将运行该函数的handler方法。可以采用可执行文件(名为 bootstrap)的形式将Runtime包含在函数的部署包中。

Runtime负责运行函数的初始代码、从环境变量读取handler名称以及从 Lambda runtime API 中读取调用事件。Runtime会将事件数据传递到函数hanldler,并将来自handler的响应发回 Lambda。

Lambda Runtime Bootstrap

Runtime Bootstrap 是一个Linux兼容的可执行文件,在 Runtime HTTP API 和 要执行的函数之间扮演桥梁的角色,如下图所示:

Bootstrap需要负责 response/error 的处理,context 的创建和函数的执行。

Lambda Runtime的使用

可以在创建或更新函数时选择自定义runtime,自定义 Runtime 以 Lamdba Layer 的形式发布,所以通常函数的第一个Layer 往往是 runtime。

自定义runtime在标准 Lambda 执行环境中运行。它可以是 Shell 脚本(采用包含在 Amazon Linux 中的语言),也可以是在 Amazon Linux 中编译的二进制可执行文件。

要使用自定义runtime,需要将函数的运行时设置为 provided。而自定义runtime可包含在函数的部署包中,或包含在Layer中。Lamdba 将先在部署包中寻找 bootstrap 文件,如果没有找到,则在函数的Layer中寻找。

开发Lambda Runtime

可以采用任何编程语言实现 AWS Lambda Runtime,AWS目前推荐的方式是通过Lambda Runtime来为 Lambda 提供新语言或者新语言版本的支持。

AWS 表示:Runtime API是我们在Lambda中支持新语言的未来。

已提供的Layer和Runtime API

https://github.com/mthenw/awesome-layers

Awesome Layers 项目收集了目前可用的 Lambda Layers,按种类分为语言运行时(Java,Node,Rust,ballerina),工具(OCR,Format Convert),监控(Datadog,Epsagon Node,iopipe),安全(Protego,PureSec,Twistlock)。

总结

  • 关注点分离

    Lambda Layers 可以分离依赖和业务逻辑之间的关注点,让函数代码更加集中在业务逻辑

  • 加快部署

    因为依赖可以重用,部署包的大小可以大为缩减,减少空间占用和网络传输

  • 标准化

    Layer提供的功能和原来的类库等方式并无不同,但是在Layer的帮助下可以实现更好的依赖/组件标准化。包括以 Runtime API 形式出现的编程语言支持。

  • 提供容器/镜像外的另一个解决方案

    在不使用容器和镜像的情况下,Lambda Runtime API 和 Lambda Layers 之间的组合也可以实现容器和镜像的部分功能。

  • 可以配合容器使用

    即使有容器的支持,也可以结合使用 Layer 和 容器:可以根据实际需要选择是将依赖打包到镜像,还是使用标准 Layer。

参考资料

介绍文章:

Slides:

视频:

教程:

4.2.2 - Lambda资料收集

AWS Lambda项目资料收集

官方资料

官方文档

社区资料

学习资料

2016年

视频资料

4.3 - AWS Event Bridge

AWS Event Bridge项目

4.4 - 微软Azure Functions项目

微软Azure Functions项目

4.4.1 - Azure Functions

微软Azure Functions项目

Azure Functions 是一种事件驱动型计算体验,通过它可执行采用所选编程语言编写的代码,而不必担心服务器的问题。得益于按需扩展,绝不为闲置容量付费。

介绍

无服务器计算的介绍

暂时不考虑基础结构,更快地生成应用

无服务器计算的承诺

如果可以将所有时间都花在生成和部署强大应用上,而无需花时间管理服务器,这会有什么不同?由于为你托管了需要运行并缩放应用的基础结构,无服务器计算可做到这一点。将精力集中在业务上。将资源从基础结构管理重定向到创新,使应用更快上市。

什么是无服务器计算?

无服务器计算是服务器、基础结构和操作系统的抽象化。生成无服务器应用时,不需要预配和管理任何服务器,这样便可将注意力从基础结构问题上移开。无服务器计算由云中准实时发生的对事件和触发器的反应驱动。作为完全托管服务,服务器管理和容量规划对开发人员来说不可见,且仅基于消耗的资源或代码运行的实际时间计费。

为什么生成无服务器应用?

  • 从完全托管的服务获益

    减轻团队管理服务器的负担。通过利用完全托管的服务,专注于商业逻辑并避免繁重的管理任务。通过无服务器体系结构,只需部署代码,它随即就会以高可用性运行。

  • 灵活缩放

    无服务器计算从零扩展到瞬间(几秒钟内)处理数万个并发函数,可匹配任何工作负载,而无需进行缩放配置 - 它对事件和触发器做出准实时反应。

  • 只为使用的资源付费

    通过无服务器体系结构,只需为代码运行的时间付费。无服务器计算由事件驱动,一旦由事件触发资源后即会分配这些资源。仅通过次秒级计费方式,对执行代码所用的时间和资源收费。

备注:上面三个是serverless目前的主要卖点,大家的考虑和出发点都差不多,尤其是后面两个。

资料

核心概念

https://serverless.com/framework/docs/providers/azure/guide/intro/

无服务器框架可帮助您使用Azure功能开发和部署无服务器应用程序。 它是一个CLI,提供开箱即用的结构,自动化和最佳实践,使您可以专注于构建由 Functions 和 Events 组成的复杂,事件驱动,无服务器架构。

无服务器框架与其他应用程序框架不同,因为:

  • 将代码作为基础设施来管理
  • 支持多种语言(Node.js,Python,Java等)

以下是Framework的主要概念以及它们与Azure Functions的关系……

Functions

Function是Azure Function。它是一个独立的部署单元,就像微服务一样。它只是部署在云中的代码,通常用于执行单个作业,例如:

  • 将用户保存到数据库
  • 处理数据库中的文件
  • 执行计划任务

您可以在代码中执行多个作业,但我们不建议您在没有充分理由的情况下执行此操作。关注点分离是最好的,框架旨在帮助您轻松开发和部署Function,以及管理大量Function。

Events

触发Azure Function执行的任何内容都被框架视为Event。 Event是Azure功能上的平台Event,例如:

  • HTTP触发器(例如,用于REST API)
  • 预定计时器(例如,每5分钟运行一次)
  • 服务总线队列触发器(例如来自另一个Function的工作项)
  • 物联网/事件中心消息(例如,来自设备或服务的消息)
  • Webhook触发(例如,Github项目更新)
  • 和更多…

在无服务器框架中为Azure Function定义事件时,框架将自动将其转换为该事件所需的绑定,并配置Function以侦听它。

Services

Service是框架的组织单位。 您可以将其视为项目文件,但您可以为单个应用程序提供多个服务。 您可以在一个名为serverless.yml(或serverless.json或serverless.js)的文件中定义您的Function,触发它们的Event以及Function使用的资源。 它看起来像这样:

# serverless.yml

service: users

functions: # Your "Functions"
  usersCreate:
    events: # The "Events" that trigger this function
      - http: true
        x-azure-settings:
          name: req
          methods:
           - post
          route: /users/create
  usersDelete:
    events:
      - http: true
        x-azure-settings:
          name: req
          methods:
           - delete
          route: /users/delete

通过运行无服务器部署与Framework一起部署时,serverless.yml中的所有内容都会立即部署。

Plugins

您可以使用插件覆盖或扩展Framework的功能。 每个serverless.yml都可以包含一个plugins: 属性,可以有多个插件。

# serverless.yml

plugins:
  - serverless-plugin-identifier
  - serverless-another-plugin

插件是自定义JavaScript代码,用于在无服务器框架内创建新的或扩展现有命令。 无服务器框架只是核心中提供的一组插件。 如果您或您的组织有特定的工作流程,请安装预先编写的插件或编写插件以根据您的需要自定义框架。 外部插件的编写方式与核心插件完全相同。

mapping and routing events from multiple event sources to multiple target systems.

4.5 - Riff项目

Riff项目

4.5.1 - 安装riff

安装riff

安装CLI

Linux

在ubuntu16.04上安装:

sudo wget -q -O - https://raw.githubusercontent.com/starkandwayne/homebrew-cf/master/public.key | apt-key add -
sudo echo "deb http://apt.starkandwayne.com stable main" | tee /etc/apt/sources.list.d/starkandwayne.list
sudo apt-get update
sudo apt-get install riff

也可以直接下载安装,下载地址: https://github.com/projectriff/riff/releases

curl -Lo riff-linux-amd64.tgz https://github.com/projectriff/riff/releases/download/v0.1.1/riff-linux-amd64.tgz
tar xvzf riff-linux-amd64.tgz
sudo mv riff /usr/local/bin/

4.5.2 - Riff概述

Riff项目

riff logo

介绍

riff的介绍,看到一下几个说法:

  • riff is for functions
  • riff is a CLI for functions on Knative
  • riff项目建立在Knative项目的build,serving和eventing特征之上。

在riff的首页,看到三个描述:

  1. Functions are packaged as containers/ Function以容器方式打包
  2. Sidecars connect functions with event brokers / sidecar用event broker连接function
  3. Functions scale with events / Function随事件扩展

riff的网站:

资料

演讲资料

4.6 - Google Cloud Run产品

Google Cloud Run产品

4.6.1 - Cloudrun官方介绍

cloudrun官方介绍

Cloud Run介绍

备注:来自 cloudrun官方网站首页 的介绍,虽然有广告味道,不过还是能得到一些信息的。

首先是 Cloud Run 的简短介绍:

Run stateless HTTP containers on a fully managed environment or in your own GKE cluster.

在完全托管的环境或者自己的GKE集群中运行serverless HTTP容器。

介绍内容

  • 将serverless带入容器

    Cloud Run是一个托管计算平台,使您可以运行通过HTTP请求可调用的无状态容器。Cloud Run是serverless的:它抽象出所有基础设置管理,因此您可以专注于最重要的事情 - 构建出色的应用。它由 Knative构建,允许您选择运行容器的方式:使用Cloud Run的完全托管,或者在GKE上使用Cloud Run运行的Google Kubernetes Engine集群。

  • 容器在几秒钟内生产

    许多serverless平台有对语言,库的支持限制,甚至限制编码方式。通过允许轻松部署监听HTTP请求的任意serverless容器,Cloud Run使您能够以自己的方式编写代码。容器提供工作负载的灵活性和可移植性。使用Cloud Run,可以使用喜欢的依赖项和工具,以喜欢的语言构建出色的应用程序,并在几秒钟内完成部署。

  • 原生serverless

    Cloud Run使您可以运行serverless HTTP工作负载,而不必操心服务器。它抽象出所有基础设施管理,例如配置和管理服务器,因此您只关注编写代码。根据流量,它几乎可以立即自动从零开始向上和向下扩展,因此您无需担心规模配置。Cloud Run还仅针对使用的资源(计算到最接近的100毫秒)收费,因此您永远不必为超额配置的资源付费。

  • 一致体验

    将具有开发人员一致体验的serverless容器部署到完全托管的环境或您自己的GKE集群。Knative是一种基于Kubernetes的开放API和运行时环境,可以让您自由地在不同的环境和平台上移动工作负载:GCP完全托管,GKE,或Knative运行的任何地方。

点评:cloud run的介绍,强调的重点是"Container on serverless",而不是以往的 “Function on Serverless”。cloud run 支持的是基于容器的工作负载,因此适用范围远远大于传统的FaaS。其次强调的是一致性的体验,在不同平台的可移植性,含蓄的表达了不会出现供应商和平台Lock-In。

特性

  • 开发简单

    简单的命令行和用户界面,可以快速部署和管理服务

  • 快速自动缩放

    Cloud Run会根据流量自动从零向上或向下扩展到N. 在GKE上运行时,自动扩展限制在GKE集群的容量范围内。

  • 托管式

    无需管理基础设施:一旦部署,Cloud Run将管理您的服务,以便您可以安然入睡。

  • 任何语言/库/二进制文件

    使用您选择的编程语言,任何语言或操作系统库,甚至自带二进制文件。

  • 利用容器工作流程和标准

    容器已成为打包和部署代码及其依赖项的标准。Cloud Run与容器生态系统配对很好:Cloud BuildContainer Registry,Docker。

  • 冗余

    Cloud Run服务是区域性的,可跨多个区域自动复制

  • 集成的日志和监控

    与Stackdriver监控,日志和错误报告的集成,开箱即用,确保应用的健康。

  • 建立在Knative上

    Cloud Run构建于Knative开源项目之上,可实现工作负载的跨平台可移植性。

  • 自定义域名

    将您的服务映射到您自己的域名。

点评:和其他serverless托管服务相比,亮点主要还是对容器的支持带来的负载适用范围广泛。

选择适合的平台

Cloud Run使您可以灵活地在Google Cloud或Google Kubernetes Engine上运行服务。如果您已经在使用GKE,则Cloud Run可以部署到您的群集中,允许访问自定义计算机类型,额外的网络和GPU支持,以扩展Cloud Run服务的运行方式。最棒的是您可以稍后轻松改变主意,从Cloud Run切换到在GKE上的Cloud Run,反之亦然,而无需重新实现您的服务。

Cloud Run GKE上的Cloud Run
价钱 按使用付费(见下文)。 作为Kubernetes Engine的一部分提供。定价将在GA之前确定。
机器类型 每个实例一个vCPU,可以更改内存 GKE上的标准或自定义机器类型,包括GPU。
身份和政策 管理允许调用服务的身份(或允许未经身份验证的调用)。 将服务发布到Internet或仅将其提供给群集或VPC网络。
联网 无法访问VPC /计算引擎网络。服务不是Istio服务网格的一部分。 访问VPC /计算引擎网络。服务参与Istio服务网格。
网址 自动提供URL和SSL证书 自定义域仅包含手动SSL证书。

点评:cloud run是完全托管的版本,因此可以按照使用付费,可以提供各种集成,甚至,实际托管的knative实现很有可能和开源的 knative 不同。而GKE上的Cloud Run就没有这个自由度了,应该是用开源版本的 knative。

价钱

  • Cloud Run

    仅为使用的资源收取费用,计费到最近的100毫秒。

  • Cloud Run on GKE pricing

    GKE上的Cloud Run是Google Kubernetes Engine集群的附加组件。Cloud Run on GKE部署的工作量包含在您的GKE定价中。GRE上Cloud Run的最终定价将在GA之前确定。Google Kubernetes Engine的价格基于群集的预配资源。

Cloud Run计费模型

Cloud Run 的计费模型也颇具创新性:它不像 Fargate 那样完全按请求数目计费,而是将所有并发的请求算在一个计费单位内,这有望大大减低用户需要支付的成本。

https://cloud.google.com/run/pricing

Cloud Run仅针对您使用的资源收取费用,四舍五入到最接近的100毫秒。请注意,每个资源都有免费配额。总Cloud Run帐单将是定价表中资源的总和。

免费配额每月重置; 您只需支付超过免费配额的使用费。

可计费时间

对于给定的容器实例,可计费时间发生时

  • 容器实例正在启动
  • 容器实例正在处理至少一个请求

只有在容器实例上请求处于活动状态时分配的CPU和内存才会收费,并向上舍入到最接近的100毫秒。

如果容器实例同时收到许多请求,则可计费时间从第一个请求的开始开始,到最后一个请求结束时结束,如下图所示:

对于运行在GKE上的Cloud Run,由于GKE上的Cloud Run是Google Kubernetes Engine的附加组件。群集中运行的工作负载包含在Google Kubernetes Engine定价中。GRE上Cloud Run的最终定价将在GA之前确定。

4.6.2 - Google Cloud Run产品概述

Google Cloud Run产品概述

在旧金山举办的 Google Cloud Next 2019 大会上,Google Cloud Run正式发布。

Cloud Run是一个类似 Microsoft Azure ACI,AWS Fargate 的容器实例服务。但与 ACI 和 Fargate 这些基于虚拟机技术栈的实现不同,Cloud Run 服务是基于 Knative 的。而 knative 是 Kubernetes 原生的 Serverless 基础设施项目。

这是业界第一个基于 Knative + Kubernetes 的 Serverless 服务。

而且,cloud run 是运行于 gVisor 之上的。

4.7 - TriggerMesh EveryBridge项目

TriggerMesh EveryBridge项目

4.7.1 - TriggerMesh EveryBridge

TriggerMesh EveryBridge项目

4.8 - Solace Event Mesh

Solace Event Mesh项目

4.8.1 - Event Mesh概述

Solace Event Mesh项目

Solace介绍

官方网站:https://solace.com/ , 口号:

“Building the digital backbone for real-time enterprises.” 为实时企业构建数字骨干

描述语:

Everything you need to get your business events streaming on an event mesh, plus what you need to discover, manage and govern them.

在 Event Mesh 上流式传输业务事件所需的一切,以及发现、管理和管理它们所需的一切。

pubsub+

Pubsub+ 号称 “The complete event management platform / 完整的事件管理平台”:

Event Broker

At the run-time data movement level, PubSub+ event brokers power an event mesh, a modern messaging layer that can be deployed across every environment and component of the distributed enterprise, to stream events across them all.

在实时数据移动级别,PubSub+ Event Broker 为 Event Mesh 提供支持,Event Mesh 是一种现代的消息传递层,可以在分布式企业的每个环境和组件中进行部署,并在他们之间流式传输事件。

Event Mesh Management

To manage the infrastructure, PubSub+ event mesh management and monitoring solutions make it easy to deploy event brokers, create event meshes, and optimize the health and performance of the event-driven system.

为了管理基础设施,PubSub+ Event Mesh 管理和监视解决方案可以简化部署Event Broker ,创建 Event Mesh 以及优化事件驱动系统的运行状况和性能。

Streaming Intergrations

At the integration level, PubSub+ APIs and Streaming Integrations provide a variety of on-ramps and off-ramps to the event mesh, including support for open standard protocols and APIs (MQTT, AMQP, JMS, REST) as well as proprietary messaging APIs to connect legacy and modern applications, edge streaming technologies (StreamSets, Striim, Adaptris, ASAPIO, Dell Boomi) to integrate 3rd party applications and connectors for technologies like Apache Kafka.

在集成级别上,PubSub+ API 和 Streaming 集成为 Event Mesh 提供了各种渠道,包括支持开放标准协议和API(MQTT,AMQP,JMS,REST),以及支持专有消息API以连接旧的和现代的应用程序,支持边缘流技术(StreamSets,Striim,Adaptris,ASAPIO,Dell Boomi)以为Apache Kafka等技术集成第三方应用程序和连接器。

Event Portal

At the application level, PubSub+ Event Portal gives developers and architects tools to design, describe and discover events within their system, and to see the relationships between applications and events, making event-driven applications and microservices easier to design, deploy and evolve.

在应用程序级别,PubSub+ Event Portal为开发人员和架构师提供了工具来设计,描述和发现系统中的事件,并查看应用程序和事件之间的关系,从而使事件驱动的应用程序和微服务更易于设计,部署和发展。

Security

PubSub+ Platform enables messaging architectures that deliver consistent multi-protocol client authentication and authorization security across the enterprise, deeply integrated with enterprise authentication services using a minimal set of components.

PubSub+ 平台支持使消息传递架构能够在整个企业范围内提供一致的安全性,包括多协议客户端身份验证和授权,并使用最少的组件集与企业身份验证服务进行了深度集成。

Cloud Console

All of the above features and capabilities can be accessed through a single Cloud Console with a single log-in, making it easy for architects, developers and other users to work, collaborate and drive the enterprise’s EDA mission forward.

上述所有特性和能力都可以通过单一登录的单个 Cloud Console 进行访问,从而使架构师,开发人员和其他用户可以轻松地工作,协作并推动企业的EDA远景向前发展。

4.8.2 - Pubsub+ Event Broker

Pubsub+ Event Broker介绍

Event Broker的自我介绍(来自官方资料):

The only unified event broker technology available as run-anywhere software, purpose-built hardware, and a managed service that you can use together to stream events across your distributed enterprise.

唯一的统一事件代理技术,可作为随处运行的软件,专用硬件和托管服务使用,可以一起使用以跨整个分布式企业流式传输事件。

详细描述

  • Power Your Event-Driven Transformation / 支持事件驱动转型

    Solace PubSub+ Event Broker有效地跨云,本地和物联网环境流式传输事件和信息。PubSub+ 中的“ +”表示它支持除发布/订阅(publish/subscribe)之外的各种消息交换模式,包括请求/答复(request/reply),流传输(streaming)和重播(replay),以及不同的服务质量,例如尽力而为(best effort)和有保证的传递。 它可以作为设备,软件和服务使用。 所有选项均提供相同的功能和管理体验。

  • Build an Event Mesh and Share Data Everywhere / 建立 Event Mesh 并在任何地方共享数据

    PubSub+可让您连接事件代理以组成 Event Mesh —— Event Mesh 是一个架构层,可让您将事件从一个应用程序动态路由到任何其他应用程序,无论这些应用程序部署在何处(非云,私有云,公共云)),因此您可以连接和编排微服务,将事件从本地记录系统推送到云服务,并实现跨LoB和IoT的数字化转型。

  • Unlock your data – no matter where it is / 解锁数据–无论在何处

    将我们的API用于最流行的编程语言,或者使用您喜欢的open API和协议,以便您可以连接到任何应用程序,采用同类最佳的消息传递方法,而永远不会被任何技术锁定,包括我们。

三种部署选项

  • Cloud/云

    Event Broker:Cloud 是一项托管服务。 在几分钟内启动事件代理服务,扩展到任何级别,并将消息传递基础设施的运维留给我们。 提供免费服务。

  • Software/软件

    Event Broker: Software 可以很容易的部署在您喜欢的云,容器和iPaaS / PaaS环境中。 并且有一个免费的生产就绪版本。

  • Hardware

    Event Broker: Hardware 以紧凑的外形尺寸为您提供出色的性能和容量,并且具有交钥匙设备(turnkey appliance)的可运维性和较低的TCO。

优势所在

世界领先公司依赖PubSub+ Event Broker的更多原因:

您的系统已与业界最强大,经过考验的最可靠事件代理技术联系在一起,可以放心使用。 无论您具有本地记录的 ESB /消息系统,或者云原生服务和业务应用程序的本地数据库系统,还是甚至作为终端的Kafka集群,PubSub +都可以使您的架构体系结合在一起,从而受益于所有最佳技术。

详细展开:

  • Management & Governance / 管理 & 治理
    • Centralized administration / 集中化管理
    • Authentication, authorization and encryption of assets and information / 资产和信息的认证、鉴权和加密
    • Powerful and proactive monitoring and alerting, including integration with existing monitoring tools / 强大而主动的监控和告警,包括和现有监控工具的集成
    • Built-in high availability and automated disaster recovery / 内置高可用性和自动灾难恢复
  • Federated Architecture / 联邦架构
    • Routing across geographically distributed cloud and on-premises environments / 跨地理分布的云和本地环境进行路由
    • Dynamic, self-learning routing / 动态的,自我学习的路由
    • Fast, bandwidth-efficient routing over wide area networks / 在广域网上进行快速,高效带宽的路由
  • Capacity and Performance / 容量和性能
    • 28 million non-persistent and 6 million persistent messages/second per appliance / 每个设备每秒2800万非持久消息和600万持久消息
    • 1.75 million non-persistent and 235,000 persistent messages/second per software broker / 每个软件代理每秒175万非持久消息和235,000持久消息
    • Up to 200,000 concurrent IoT connections per appliance / 每个设备最多200,000个并发IoT连接
  • Advanced Messaging Capabilities / 高级消息能力
    • Message caching and replay / 消息缓存和重播
    • Sophisticated topics including wildcards / 复杂的主题,包括通配符
    • Prioritization, dead message queues / 优先级,死信队列
    • In-service upgrades / 服务中(不间断)升级

DMR

DMR 指 Dynamic Message Routing / 动态消息路由。

介绍来自: https://solace.com/wp-content/uploads/2019/02/DMR.pdf

DMR 的 功能描述简单说是:

Automatic distribution of events and subscriptions across many brokers to enable event mesh

在众多代理之间自动分发事件和订阅,以启用 Event Mesh

随着业务的增长,应用程序和微服务将变得越来越复杂,基础设施将分布在各种越来越多的环境中,包括本地数据中心,私有云,公共云和物联网。这引入了对事件驱动架构(EDA)的需求,该架构可以跨众多位置和接口动态路由信息。

动态消息路由(DMR)是一种自我学习的路由机制,可自动在 PubSub+ 事件代理之间分发订阅和事件,因此您的应用程序和设备可以共享信息,就像它们已连接到同一事件代理一样,而无需了解任何应用程序正在创建或使用数据。

开启 Event Mesh

Event Mesh 是一个架构层,它使来自一个应用程序的事件能够动态路由并被其他任何应用程序接收,无论这些应用程序部署在何处(非云,私有云或公共云)。 DMR通过连接环境内部或环境之间的 PubSub+ 事件代理来启用 Event Mesh。这使您可以轻松扩展环境中的容量或跨多个环境连接应用程序。

在云或数据中心内扩展容量

可以使用 DMR 快速增加任何云或数据中心内的代理容量。

使用DMR,您可以快速将新的HA组(Triplets / 三元组)连接到网络,以使它们自动获知所有订阅,包括持久性订阅和非持久性订阅,这样,感兴趣的消费者与其中任何一个相连都可以获取由任何生产者发布的事件。

启用分布式环境之间的数据流

可以使用DMR连接运行在不同云和数据中心中的代理,以便事件可以在它们之间流动。

一旦配置了双向DMR链接,订阅就会自动传播到企业网络中的所有其他代理。 然后,当应用程序发布事件时,事件会自动分发到世界各地的所有订阅的客户端。

监控

https://solace.com/products/monitor/

PubSub+ Monitor :

Proactively monitor your brokers so that you can keep your finger on the pulse of mission-critical applications.

主动监视代理,以便可以随时掌握关键任务的应用程序。

Detect issues before they impact end users by using Monitor’s dashboards and alerts on critical broker metrics and events.

通过使用Monitor的仪表板和关键代理指标和事件的警报,在问题影响最终用户之前检测出问题。

获取需要的可行告警

根据预先配置的阈值和状态事件发送主动告警,以帮助运营团队定位开发问题并优化系统性能。

关键能力

  • 改善正常运行时间

    通过允许解决和系统、VPN和客户端相关的事件的主动警报,提高正常运行时间,性能和安全性

  • 持续优化

    通过收集代理指标和事件,并存储起来以进行分析和使用,来帮助优化性能

  • 看到趋势

    提供历史趋势和可行的见解,以优化终端用户服务

  • 避免集成麻烦

    消除了构建本地产品或购买第三方监控解决方案的需要

与现有的其他监视解决方案不同,PubSub + Monitor意味着:

  • 没有更多的选择

    实时收集指标和状态事件

  • 预配置

    包括许多预配置的阈值和警报

  • 易于部署

    采用无代理架构,因此您可以快速滚动

  • 一站式

    统一监视所有 PubSub+ 软件和硬件代理

消息缓存

https://solace.com/products/cache/

PubSub+ Cache的描述:

A scalable and flexible last value cache solution that PubSub+ customers count on.

PubSub+客户可信赖的可扩展且灵活的最终值缓存解决方案。

Group multiple PubSub+ Cache instances into a cluster to provide load balancing and fault tolerance.

将多个PubSub+缓存实例分组到一个群集中以提供负载平衡和容错能力。

“last value cache” 指的是缓存最后一个有效值。

为全球企业提供强大的缓存功能。

快速响应客户对最新发布数据的请求,同时每秒缓存数百万条消息。 将PubSub+缓存与PubSub+事件网格集成,并使用PubSub+ Manager对其进行管理。

Resiliency Need a reliable solution with low latency? We’ve got you covered. Deploy PubSub+ Cache in clusters and we’ll take care of the rest.

Speed & Scalability Service clients in real-time as your business grows in global and distributed environments. Cache almost 2 million messages/sec per instance and send up to 465,000 messages/sec to clients requesting cached messages. Add more clusters for even higher performance.

Flexibility Use your Solace API of choice to connect your subscribers. Add message plug-ins to examine, process and apply custom business rules to the data before caching.

4.9 - Pivotal Function Service项目

Pivotal Function Service

4.9.1 - Pivotal Function Service概述

Pivotal Function Service项目介绍

https://pivotal.io/platform/pivotal-function-service

特性

PFS特性介绍,来自PFS网站首页:

  • 可插拔构建系统

    PFS具有源到容器的机制,用于简化部署。 使用经过验证的组件如Cloud Foundry Buildpacks。

  • 可插拔Event Source

    PFS事件源有助于从各种外部事件源(如GitHub webhooks,blob存储和数据库服务)创建Feeds。

  • 可插拔Event Broker

    PFS可以与流行的消息代理轻松连接,如Kafka,Google Pub/Sub和RabbitMQ。 这些为消息传递通道提供了可靠的支持服务。

    备注:knative没有RabbitMQ的支持,难道是PFS扩展的?

  • 可插拔的Invoker

    Pivotal将继续在PFS中开发riff调用程序模型,使开发人员能够使用简单的语言惯用接口提供流和非流功能代码。

  • 事件扩展

    自动缩放,从0到1,从1到N个实例,然后返回到零个实例。

  • 在Kubernetes和Istio上运行

    PFS可以帮助您体现Kubernetes和Istio的优势,即使它抽象出两种技术的复杂性。

  • 使用带有函数的现代DevOps工作流程

    PFS允许您使用熟悉的,基于容器的工作流程来实现serverless方案。

  • 多语种

    PFS支持在您选择的框架中创建函数 - Node.js,Spring / Java,Go,Python和Shell。

5 - 函数编排

介绍serverless的函数编排

5.1 - AWS Step Function

介绍AWS Step Function

5.1.1 - AWS Step Function概述

AWS Step Function概述

介绍

https://aws.amazon.com/cn/step-functions/

功能介绍

Step Function官方网站的介绍是:使用可视工作流来构建分布式应用程序

AWS Step Functions 让您将多个 AWS 服务协调为无服务器工作流,以便您可以快速构建和更新应用程序。使用 Step Functions,您可以设计和运行将 AWS Lambda 和 Amazon ECS 等服务整合到功能丰富的应用程序中的工作流。工作流由一系列步骤组成,一个步骤的输出充当下一个步骤的输入。使用 Step Functions,应用程序开发更简单、更直观,因为它将工作流转换为易于理解、易于向其他人说明且易于更改的状态机示意图。您可以监控执行的每个步骤,这意味着您可以快速识别并解决问题。Step Functions 可以自动触发和跟踪各个步骤,并在出现错误时重试,因此您的应用程序能够按照预期顺序执行。

来自Lambda网站对 Step Function 的介绍:

可以通过使用 AWS Step Functions 构建工作流来协调多个 AWS Lambda 函数,用于复杂或长时间运行的任务。

通过 Step Functions,可以定义使用顺序、并行、分支和错误处理步骤来触发 Lambda 函数集合的工作流。借助 Step Functions 和 Lambda,可以为应用程序和后端构建有状态、长时间运行的进程。

优势

  • 快速构建和更新应用程序

    AWS Step Functions 允许您构建可快速将业务需求转换为技术需求的可视化工作流。您可以在大约几分钟内构建应用程序,并且当需求变化时,您可以交换或重新组织组件而无需自定义任何代码。

  • 提高弹性

    AWS Step Functions 为您管理状态、检查点和重启,以确保您的应用程序按照预期逐步执行。内置 try/catch、重试和回滚功能自动处理错误和异常。

  • 编写更少代码

    AWS Step Functions 为您管理应用程序的逻辑,并实施基本基元,例如分支、并行执行和超时。这删除了可能在微服务和函数中重复的额外代码。

工作原理

使用案例

在aws的博客网站中有很多内容,可以作为案例研究,虽然有广告嫌疑,但是还是很有参考价值

https://aws.amazon.com/cn/blogs/architecture/

后面有时间再做一个详细的使用案例收集和场景分析,以判断是否有合适的场景可以适用于我们自己的产品

数据处理

Step Functions 可帮助确保长时间运行的多个 ETL 作业按顺序执行并成功完成,而非手动编排这些作业或维护单独的应用程序。您还可以使用 Step Functions 标准化 Machine Learning 训练工作流以提高 Machine Learning 模型的准确度。

备注:ETL和Machine Learning的场景

案例:官方案例里面有一个ETL的案例,Orchestrate multiple ETL jobs using AWS Step Functions and AWS Lambda

自动执行任务

Step Functions 提供了常规部署、升级、安装和迁移的可审核自动化。您可以使用 Step Functions 来轻松地自动执行周期性任务,例如补丁管理、基础设施选择和数据同步,并且 Step Functions 将自动扩展、响应超时和重试失败的任务。

使整体实现现代化

通过使用 Step Functions 将一些任务与代码库的其余部分分离,您可以处理整体应用程序向作为一系列小步骤的微服务的转换。这样,您可以安全地按照自己的进度清理业务关键型代码,而不会中断操作,同时可继续交付新功能。

备注:这是在微服务改造期间剥离部分功能?

应用程序编排

使用 Step Functions 将多个 AWS Lambda 函数组合到响应式无服务器应用程序和微服务中,而不必为工作流逻辑、并行进程、错误处理、超时或重试编写代码。您还可以编排在​ Amazon EC2 实例、容器或本地服务器上运行的数据和服务。

备注:这才是真正的函数编排,组合现有多个函数成为一个新的函数或者服务