「无服务器架构」Openwhisk 系统架构概览

简介: 「无服务器架构」Openwhisk 系统架构概览

OpenWhisk是一个事件驱动的计算平台,也称为无服务器计算或功能即服务(FaaS),用于响应事件或直接调用而运行代码。下图显示了高级OpenWhisk体系结构。




事件的示例包括数据库记录的更改,超过特定温度的IoT传感器读数,将新代码提交到GitHub存储库或来自Web或移动应用程序的简单HTTP请求。来自外部和内部事件源的事件通过触发器进行传递,并且规则允许操作对这些事件做出反应。

操作可以是小的代码片段(支持JavaScript,Swift和许多其他语言),也可以是嵌入在Docker容器中的自定义二进制代码。每当触发触发器时,OpenWhisk中的操作就会立即部署并执行。触发次数越多,调用的动作越多。如果没有触发触发器,则不会运行任何操作代码,因此没有成本。

除了将动作与触发器相关联之外,还可以通过使用OpenWhisk API,CLI或iOS SDK直接调用动作。一组动作也可以链接在一起,而无需编写任何代码。依次调用链中的每个动作,并将一个动作的输出作为输入传递到序列中的下一个动作。

对于传统的长期运行的虚拟机或容器,通常的做法是部署多个VM或容器以抵御单个实例的故障。但是,OpenWhisk提供了一种替代模型,没有与弹性相关的成本开销。按需执行操作可提供固有的可伸缩性和最佳利用率,因为正在运行的操作数始终与触发率匹配。此外,开发人员现在只关注代码,而不必担心监视,修补和保护基础服务器,存储,网络和操作系统基础结构。

与其他服务和事件提供程序的集成可以随包一起添加。一揽子计划是一堆提要和操作。提要是一段代码,用于配置外部事件源以触发触发事件。例如,使用Cloudant变更Feed创建的触发器将配置服务,以在每次文档被修改或添加到Cloudant数据库时触发该触发器。包中的动作表示服务提供者可以提供的可重用逻辑,以便开发人员不仅可以将服务用作事件源,还可以调用该服务的API。

现有的软件包目录提供了一种快速的方法来增强具有有用功能的应用程序,并访问生态系统中的外部服务。启用了OpenWhisk的外部服务的示例包括Cloudant,The Weather Company,Slack和GitHub。

OpenWhisk的工作方式

作为一个开源项目,OpenWhisk站在Nginx,Kafka,Docker,CouchDB等巨头的肩膀上。所有这些组件共同构成了“无服务器基于事件的编程服务”。为了更详细地解释所有组件,让我们跟踪动作在系统发生时的调用。无服务器引擎的核心工作是OpenWhisk中的调用:执行用户输入到系统中的代码,并返回执行结果。

创建动作

为了提供一些上下文说明,我们首先在系统中创建一个动作。我们将在稍后浏览系统时使用该操作来解释概念。以下命令假定已正确设置OpenWhisk CLI。

首先,我们将创建一个包含以下代码的action.js文件,该代码会将“ Hello World”打印到标准输出,并在键“ hello”下返回一个包含“ world”的JSON对象。

function main() { console.log('Hello World'); return { hello: 'world' }; }

我们使用创建该动作。

wsk action create myAction action.js

做完了 现在我们实际上要调用该动作:

wsk action invoke myAction --result

内部处理流程

OpenWhisk幕后实际上发生了什么?


进入系统:nginx

第一:OpenWhisk的面向用户的API完全基于HTTP,并采用RESTful设计。因此,通过wsk CLI发送的命令实际上是针对OpenWhisk系统的HTTP请求。上面的特定命令大致翻译为:

POST /api/v1/namespaces/$userNamespace/actions/myAction Host: $openwhiskEndpoint

注意这里的$ userNamespace变量。用户可以访问至少一个名称空间。为了简单起见,假设用户拥有放置myAction的名称空间。

进入系统的第一个入口是通过nginx,“ HTTP和反向代理服务器”。它主要用于SSL终止并将适当的HTTP调用转发到下一个组件。

进入系统:控制器

对我们的HTTP请求没有做很多事情,nginx将其转发到Controller,这是我们通过OpenWhisk进行的下一个组件。它是实际REST API(基于Akka和Spray)的基于Scala的实现,因此可以用作用户可以做的所有事情的接口,包括在OpenWhisk中对实体的CRUD请求和动作的调用(这就是我们的现在正在做)。

控制器首先消除用户要做什么的歧义。它基于您在HTTP请求中使用的HTTP方法来执行此操作。根据上面的翻译,用户向现有动作发出POST请求,控制器将其转换为动作的调用。

鉴于控制器的中心作用(因此得名),以下步骤在一定程度上都会涉及它。

身份验证和授权:CouchDB

现在,控制器将验证您的身份(身份验证),以及您是否有权对实体执行您想做的事情(授权)。将根据CouchDB实例中的所谓主题数据库验证请求中包含的凭据。

在这种情况下,将检查用户是否存在于OpenWhisk的数据库中,并检查该用户是否有权调用动作myAction,我们假设该动作是用户拥有的命名空间中的动作。后者有效地赋予了用户调用该操作的特权,这是他希望执行的操作。

一切正常后,门打开,进入下一阶段的处理。

采取行动:再次CouchDB…

由于Controller现在确定允许用户进入并具有调用其操作的特权,因此它实际上是从CouchDB的拂数据库中加载了此操作(在本例中为myAction)。

动作记录主要包含要执行的代码(如上所示)和要传递给动作的默认参数,并与实际调用请求中包含的参数合并。它还包含执行时对其施加的资源限制,例如允许使用的内存。

在这种特殊情况下,我们的操作没有任何参数(该函数的参数定义是一个空列表),因此我们假设我们没有设置任何默认参数,也没有向该操作发送任何特定的参数,从这个角度来看,最琐碎的情况。

谁来执行该操作:负载均衡器

作为控制器一部分的负载均衡器通过连续检查其运行状况来全局查看系统中可用的执行器。这些执行者被称为祈求者。知道哪些可用的调用程序的负载均衡器会选择其中之一来调用请求的操作。

请排队:Kafka

从现在开始,您发送的调用请求可能主要发生两件事:

  • 系统可能崩溃,丢失您的调用。
  • 系统可能会承受如此沉重的负担,以至于调用需要先等待其他调用才能完成。

两者的答案都是Kafka,“一个高吞吐量,分布式,发布-订阅消息系统”。Controller和Invoker仅通过Kafka缓冲和保留的消息进行通信。这样就减轻了控制器和调用者的内存缓冲负担,并冒出OutOfMemoryException的风险,同时还确保在系统崩溃的情况下不会丢失消息。

为了调用该动作,控制器将消息发布到Kafka,其中包含要调用的动作和传递给该动作的参数(在本例中为无)。该消息发送给控制器从上方从可用调用者列表中选择的调用者。

Kafka确认收到消息后,将使用ActivationId响应对用户的HTTP请求。用户稍后将使用它来访问此特定调用的结果。请注意,这是一个异步调用模型,在该模型中,一旦系统接受了调用某个动作的请求,HTTP请求就会终止。可以使用同步模型(称为阻塞调用),但本文不会介绍。

实际上已经在调用代码了:调用者

调用程序是OpenWhisk的心脏。调用者的职责是调用一个动作。它也在Scala中实现。但是还有更多的东西。为了以隔离和安全的方式执行操作,它使用Docker。

Docker用于为我们以快速,隔离和受控的方式调用的每个动作设置一个新的自封装环境(称为容器)。简而言之,对于每个动作调用,都会产生一个Docker容器,该动作代码被注入,并使用传递给它的参数执行该操作代码,获得结果,该容器被销毁。这也是进行大量性能优化以减少开销和缩短响应时间的地方。

在我们的特定情况下,由于手头有一个基于Node.js的操作,Invoker将启动一个Node.js容器,从myAction注入代码,不带任何参数运行它,提取结果,保存日志并销毁再次使用Node.js容器。

存储结果:再次CouchDB

由于调用者获得了结果,因此将其存储为激活数据库,作为上面进一步提到的ActivationId下的激活。激活数据库位于CouchDB中。

在我们的特定情况下,Invoker从操作中获取返回的JSON对象,获取Docker编写的日志,将它们全部放入激活记录中并将其存储到数据库中。大致如下所示:

{ "activationId": "31809ddca6f64cfc9de2937ebd44fbb9", "response": { "statusCode": 0, "result": { "hello": "world" } }, "end": 1474459415621, "logs": [ "2016-09-21T12:03:35.619234386Z stdout: Hello World" ], "start": 1474459415595, }

注意记录如何包含返回的结果和写入的日志。它还包含操作调用的开始时间和结束时间。激活记录中有更多字段,为简化起见,这是简化版本。

现在,您可以再次使用REST API(再次从步骤1开始)以获取激活,从而获得操作结果。为此,您可以使用:

wsk activation get 31809ddca6f64cfc9de2937ebd44fbb9

摘要

我们已经了解了一个简单的wsk动作如何调用myAction贯穿OpenWhisk系统的不同阶段。系统本身主要仅包含两个自定义组件,即Controller和Invoker。其他一切都已经存在,由开源社区中如此众多的人开发。

您可以在以下主题中找到有关OpenWhisk的其他信息:

  • 实体名称
  • 动作语义
  • 限度
  • REST API
相关实践学习
函数计算部署PuLID for FLUX人像写真实现智能换颜效果
只需一张图片,生成程序员专属写真!本次实验在函数计算中内置PuLID for FLUX,您可以通过函数计算+Serverless应用中心一键部署Flux模型,快速体验超写实图像生成的魅力。
从 0 入门函数计算
在函数计算的架构中,开发者只需要编写业务代码,并监控业务运行情况就可以了。这将开发者从繁重的运维工作中解放出来,将精力投入到更有意义的开发任务上。
相关文章
|
10月前
|
存储 机器学习/深度学习 数据库
阿里云服务器X86/ARM/GPU/裸金属/超算五大架构技术特点、场景适配参考
在云计算技术飞速发展的当下,云计算已经渗透到各个行业,成为企业数字化转型的关键驱动力。选择合适的云服务器架构对于提升业务效率、降低成本至关重要。阿里云提供了多样化的云服务器架构选择,包括X86计算、ARM计算、GPU/FPGA/ASIC、弹性裸金属服务器以及高性能计算等。本文将深入解析这些架构的特点、优势及适用场景,以供大家了解和选择参考。
1421 61
|
11月前
|
存储 运维 Serverless
千万级数据秒级响应!碧桂园基于 EMR Serverless StarRocks 升级存算分离架构实践
碧桂园服务通过引入 EMR Serverless StarRocks 存算分离架构,解决了海量数据处理中的资源利用率低、并发能力不足等问题,显著降低了硬件和运维成本。实时查询性能提升8倍,查询出错率减少30倍,集群数据 SLA 达99.99%。此次技术升级不仅优化了用户体验,还结合AI打造了“一看”和“—问”智能场景助力精准决策与风险预测。
1068 69
|
7月前
|
运维 监控 安全
“没服务器了,那我这运维是白干了吗?”——无服务器架构对运维的冲击与转机
“没服务器了,那我这运维是白干了吗?”——无服务器架构对运维的冲击与转机
177 0
|
8月前
|
存储 安全 虚拟化
全面解析服务器虚拟化:云计算时代的核心技术架构
服务器虚拟化是云计算的核心技术,通过资源池化提升IT效率。本文详解其原理、部署优势及在数字化转型中的关键作用,涵盖技术架构、应用场景与选型指南,助力企业构建高效灵活的云环境。
830 0
|
10月前
|
数据采集 运维 监控
Serverless爬虫架构揭秘:动态IP、冷启动与成本优化
随着互联网数据采集需求的增长,传统爬虫架构因固定IP易封禁、资源浪费及扩展性差等问题逐渐显现。本文提出基于Serverless与代理IP技术的新一代爬虫方案,通过动态轮换IP、弹性调度任务等特性,显著提升启动效率、降低成本并增强并发能力。架构图与代码示例详细展示了其工作原理,性能对比数据显示采集成功率从71%提升至92%。行业案例表明,该方案在电商情报与价格对比平台中效果显著,未来有望成为主流趋势。
439 0
Serverless爬虫架构揭秘:动态IP、冷启动与成本优化
|
11月前
|
Cloud Native Serverless 流计算
云原生时代的应用架构演进:从微服务到 Serverless 的阿里云实践
云原生技术正重塑企业数字化转型路径。阿里云作为亚太领先云服务商,提供完整云原生产品矩阵:容器服务ACK优化启动速度与镜像分发效率;MSE微服务引擎保障高可用性;ASM服务网格降低资源消耗;函数计算FC突破冷启动瓶颈;SAE重新定义PaaS边界;PolarDB数据库实现存储计算分离;DataWorks简化数据湖构建;Flink实时计算助力风控系统。这些技术已在多行业落地,推动效率提升与商业模式创新,助力企业在数字化浪潮中占据先机。
602 12
|
存储 机器学习/深度学习 应用服务中间件
阿里云服务器架构解析:从X86到高性能计算、异构计算等不同架构性能、适用场景及选择参考
当我们准备选购阿里云服务器时,阿里云提供了X86计算、ARM计算、GPU/FPGA/ASIC、弹性裸金属服务器以及高性能计算等多种架构,每种架构都有其独特的特点和适用场景。本文将详细解析这些架构的区别,探讨它们的主要特点和适用场景,并为用户提供选择云服务器架构的全面指南。
1186 18