Apache Openwhisk学习(一)
一、背景
最近中途参与的一个项目是和Serverless、Faas相关的,项目的整体架构和实现都参考了开源项目openwhisk,因此,同事们在编码时都会参考openwhisk的源码。因为以前从没有接触过这方面的知识,因此想学习下。关于Serverless和Faas的概念场景等,可以参考下,这两篇博客,Serverless 架构:用服务代替服务器和Serverless应用场景。因为我也是刚刚接触,很多地方不是很了解。
二、Openwhisk简介
OpenWhisk 是属于 Apache 基金会的开源 FaaS 计算平台官网链接, 由 IBM 在2016年公布并贡献给开源社区(github页面),IBM Cloud 本身也提供完全托管的 OpenWhisk FaaS服务 IBM Cloud Function。从业务逻辑上看,OpenWhisk 同 AWS Lambda 一样,为用户提供基于事件驱动的无状态的计算模型,并直接支持多种编程语言(理论上可以将任何语言的 runtime 打包上传,间接调用)。

Openwhisk的特点:
(1)高性能、高扩展性的分布式Faas计算平台
(2)函数的代码及运行是全部在Docker容器中进行,利用Docker引擎实现Faas函数运行的管理、负载均衡和扩展
(3)同时,Openwhisk架构中的所有其他组件(API网关、控制器、触发器)也全部运行在Docker容器中,这使得其全栈可以比较容易的部署在IAAS/PAAS平台上 。
(4)更重要的是,相比其他Faas实现,Openwhisk更像是一套完整Serverless解决方案,除了容易调用和函数管理,Openwhisk还包括了身份验证/鉴权、函数异步触发等功能。
三、系统概览
Openwhisk是一个事件驱动的计算平台,它运行代码以响应事件或直接调用,下图显示了其 体系结构:

在上述架构中,代码时基于事件(Event)触发的。事件产生于事件源(feed),而可以用于触发函数的事件源可以是多种多样的,例如数据库的更改,超过特定温度的IoT传感器读数,新提交代码到Github存储库等。事件与对应的函数代码,通过规则(Rule)绑定。通过匹配事件对应的规则,Openswhisk会触发对应的行为(Action)。值得注意的是,多个Action可以串联,完成复杂的操作。
四、Openwhisk的工作原理
作为一个开源项目,openwhisk集成了很多其他组件Nginx,Kafka,Docker,CouchDB等,为了更加详细的解释所有组件,我们可以使用下面这个例子,来追踪整个系统的调用过程。
假设我们有包含以下代码块的文件action.js:
function main() {
console.log('Hello World');
return { hello: 'world' };
}
使用下面命令创建动作
wsk action create myAction action.js
现在,我们可以使用以下命令调用该操作:
wsk action create myAction action.js
那么我现在来看看在Openwhisk中具体发生了什么,整个过程如下图所示:

(1)Nginx
Openwhisk面向用户的API完全基于HTTP,遵循Restful设计,因此,通过wsk-cli发送的命令本质上是向其发送HTTP请求,上面的命令大致可以翻译为:
POST /api/v1/namespaces/$userNamespace/actions/myAction
Host: $openwhiskEndpoint
此处的Nginx主要用于接受Http请求,并将处理后的Http请求直接转发给controller
(2)控制器(Controller)
控制器是真正开始处理请求的地方。控制器使用Scala语言实现,并提供了对应的Rest API,接受Nginx转发的请求。Controller分析请求内容,进行下一步处理。下面的很多个步骤都会和其有关系。
(3)身份验证和鉴权:CouchDB
继续用上一步用户发出的Post请求为例,控制器首先需要验证用户的身份和权限。用户的身份信息(credentials)保存在CouchDB的用户身份数据库中,验证无误后,控制器进行下一步处理。
(4)再次CouchDB,得到对应的Action的代码及配置
身份验证通过后,Controller需要从CouchDB中加载此操作(在本例中为myAction)。操作记录主要要执行的代码和要传递给操作的默认参数,并与实际调用请求中包含的参数合并。它还包含执行时对其施加的资源限制,例如允许使用的内存。
(5)Consul和负载均衡
到了这一步,控制器已经有了触发函数所需要的全部信息,在将数据发送给触发器(Invoker)之前,控制器需要和 Consul 确认,从 Consul 获取处于空闲状态的触发器的地址。Consul 是一个开源的服务注册/发现系统,在 OpenWhisk 中 Consul 负责记录跟踪所有触发器的状态信息。当控制器向 Consul 发出请求,Consul 从后台随机选取一个空闲的触发器信息,并返回。值得注意的是:无论是同步还是异步触发模式,控制器都不会直接调用触发器API,所有触发请求都会通过 Kafka 传递。
(6)发送请求进Kafka
考虑使用kafka主要是担心发生以下两种状况:
1、系统崩溃,丢失调用请求
2、系统可能处于繁重的负载之下,调用需要等待其它调用首先完成。
Openwhisk考虑到异步情况的发生,考虑异步触发的情况,当控制器得到 Kafka 收到请求消息的的确认后,会直接向发出请求的用户返回一个 ActivationId,当用户收到确认的 ActivationId,即可认为请求已经成功存入到 Kafka 队列中。用户可以稍后通过 ActivationId 索取函数运行的结果。
(7)Invoker运行用户的代码
Invoker从对应的Kafka topic中接受控制器传来的请求,会生成一个Docker容器,注入动作代码,试用传递给他的参数执行它,获取结果,消灭容器。这也是进行了大量性能优化以减少开销并缩短响应时间的地方。
(8)CouchDB存储请求结果
Invoker的执行结果最终会被保存在CouchDB的whisk数据库中,格式如下所示:
{
"activationId": "31809ddca6f64cfc9de2937ebd44fbb9",
"response": {
"statusCode": 0,
"result": {
"hello": "world"
}
},
"end": 1474459415621,
"logs": [
"2016-09-21T12:03:35.619234386Z stdout: Hello World"
],
"start": 1474459415595,
}
保存的结果中包括用户函数的返回值,及日志记录。对异步触发用户,可以通过步骤6中返回的 activationID 取回函数运行结果。同步触发的的结果和异步触发一样保存在 CouchDB 里,控制器在得到触发结束的确认后,从 CouchDB 中取得运行结果,直接返回给用户。
本文主要参考了:
(1)https://github.com/apache/incubator-openwhisk/blob/master/docs/about.md
(2)https://blog.xinkuo.me/post/apache-openwhisk.html#apache-openwhisk%E7%AE%80%E4%BB%8B
Apache Openwhisk学习(一)的更多相关文章
- Apache Flink学习笔记
Apache Flink学习笔记 简介 大数据的计算引擎分为4代 第一代:Hadoop承载的MapReduce.它将计算分为两个阶段,分别为Map和Reduce.对于上层应用来说,就要想办法去拆分算法 ...
- Apache Shiro学习-2-Apache Shiro Web Support
Apache Shiro Web Support 1. 配置 将 Shiro 整合到 Web 应用中的最简单方式是在 web.xml 的 Servlet ContextListener 和 Fil ...
- Serverless 工程实践|自建 Apache OpenWhisk 平台
作者 | 刘宇(江昱) 前言:OpenWhisk 是一个开源.无服务器的云平台,可以在运行时容器中通过执行扩展的代码响应各种事件,而无须用户关心相关的基础设施架构. OpenWhisk 简介 Open ...
- Apache Shiro 学习记录5
本来这篇文章是想写从Factory加载ini配置到生成securityManager的过程的....但是貌似涉及的东西有点多...我学的又比较慢...很多类都来不及研究,我又怕等我后面的研究了前面的都 ...
- Apache Lucene学习笔记
Hadoop概述 Apache lucene: 全球第一个开源的全文检索引擎工具包 完整的查询引擎和搜索引擎 部分文本分析引擎 开发人员在此基础建立完整的全文检索引擎 以下为转载:http://www ...
- Apache Shiro 学习记录1
最近几天在学习Apache Shiro......看了一些大神们的教程.....感觉收获不少.....但是毕竟教程也只是指引一下方向....即使是精品教程,仍然有很多东西都没有说明....所以自己也稍 ...
- Apache OFBiz 学习笔记 之 服务引擎 二
加载服务定义文件 ofbiz-component.xml:所有的服务定义文件在每个组件的ofbi-component.xml文件中 加载服务定义 例:framework/common/ofbi ...
- Apache Ignite 学习笔记(一): Ignite介绍、部署安装和REST/SQL客户端使用
Apache Ignite 介绍 Ignite是什么呢?先引用一段官网关于Ignite的描述: Ignite is memory-centric distributed database, cachi ...
- Apache Kafka学习 (一)
前言:最近公司开始要研究大数据的消息记录,于是开始研究kafka. 市面上kafka的书很少,有的也版本比较落后,于是仗着自己英文还不错,上官网直接学习. ^_^ 1. 开始 - 基本概念 学习一样东 ...
随机推荐
- LOJ #6010. 「网络流 24 题」数字梯形
#6010. 「网络流 24 题」数字梯形 题目描述 给定一个由 n nn 行数字组成的数字梯形如下图所示.梯形的第一行有 m mm 个数字.从梯形的顶部的 m mm 个数字开始,在每个数字处可以 ...
- jq相关细节-1
animate/动画 所有用于动画的属性必须是数字的,除非另有说明:这些属性如果不是数字的将不能使用基本的jQuery功能.(例如,width, height或者left可以执行动画,但是backgr ...
- Asp.net自定义控件开发任我行(6)-嵌入资源下
摘要 上一章,我们讲了嵌入.css文件,这一章,我们来讲一下嵌入.js文件,也顺带一个嵌入Image文件 内容 我们前面的几章,一运行,下拉框就显示出来了,但是DropDwonList的下拉框是被隐藏 ...
- xcode6没有prefix.pch预编译文件解决办法
注意到Xcode6创建的工程没有prefix.pch. 于是手动创建. 在other下选择pch文件 接着到工程的build setting下设置开启预编译并配置路径(文件的路径.因为我新建在cofi ...
- iOS下单例模式实现(一)(objective-c arc gcd)
单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 这里主要介绍下在arc下,利用gcd实现单例. 第一步:声明一个静态实例 static SoundTool *_instan ...
- Format aborted in 格式化namenode 失败的原因
[user6@das0 hadoop-0.20.203.0]$ bin/hadoop namenode -format 12/02/20 14:05:17 INFO namenode.NameNode ...
- BZOJ 2243:染色(树链剖分+区间合并线段树)
[SDOI2011]染色Description给定一棵有n个节点的无根树和m个操作,操作有2类:1.将节点a到节点b路径上所有点都染成颜色c:2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认 ...
- 实例对比 Julia, R, Python,谁是狼语言?
对于一个平台来说,使用者对技术本身是不敏感的,所以我们需要增加一些限制来减少集群的一些不可控情况,例如不断的写入新表/新数据却不记得删除,大量不按规范创建的表名等情况.与此同时应尽量让技术对用户透明, ...
- git filter-branch应用
1.修改author和committer git filter-branch --commit-filter ' export GIT_AUTHOR_EMAIL=me@example.com; exp ...
- 地理课(geography)
地理课(geography) 题目描述 地理课上,老师给出了一个巨大的地图,由于世界日新月异,会有一些道路在某一时刻被删除,也会有一些道路在某一时刻被修建.这里的道路均为双向的. 老师认为,有一些城市 ...