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. 开始 - 基本概念 学习一样东 ...
随机推荐
- Centos7和Centos6防火墙开放端口配置方法(避坑教学)
▲这篇文章主要为大家详细介绍了Centos7防火墙开放端口的快速方法,感兴趣的小伙伴们可以参考一下! 一.CentOS 7快速开放端口: CentOS升级到7之后,发现无法使用iptables控制Li ...
- HDU1042 A * B Problem Plus
A * B Problem Plus Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- cglib动态代理之原理说明
cglib采用了非常底层的字节码技术,通过目标类的字节码,为目标类创建子类,并在子类中用方法拦截技术,拦截所有父类方法的调用,并对拦截方法进行增强. 1)底层采用字节码框架ASM,来转换字节码来生成新 ...
- easyui-combogrid必填为空时无法通过表单验证的问题
在使用easyui-combogrid时,由于html解析出的格式是如下三层: <td> <input id="txcombo" class="easy ...
- 记一次Entity Framework 项目的优化过程
在博客园看了不少其他大神的经验.今天也抽空贡献点自己的经验(并不是说自己也是大神..小弟还只新手程序员去年才毕业的) 好了废话不多说,直接进入主题.(具体的好坏各位看官就随便看看吧..没有什么好坏之分 ...
- C# Winform打包部署时添加注册表信息实现开机启动(转载)
使用VS自带的打包模块可以很方便的对项目进行打包部署,同时我们也可以在安装部署时操作注册表实现开机启动软件.具体实现如下: 1.添加安装部署项目后,鼠标右键安装项目->视图->注册表 ...
- maven学习(十一)——maven中的聚合与继承
一.聚合 如果我们想一次构建多个项目模块,那我们就需要对多个项目模块进行聚合 1.1.聚合配置代码 <modules> <module>模块一</module> & ...
- maven学习(八)——使用maven创建javaweb项目
构建JavaWeb项目 1.创建JavaWeb项目 1.使用mvn archetype:generate命令,如下所示: mvn archetype:generate -DgroupId=com.my ...
- Markdown语法图解
Markdown语法图解 文章目录 快捷键 基本语法 对字体设置斜体.粗体.删除线 分级标题 链接 分割线 代码块 引用 列表 表格 常用技巧 换行 缩进字符 如何打出一些特殊符号 字体.字号与颜色 ...
- Codeforeces 954C Matrix Walk
题目大意 考虑一个 $x\times y$ 的矩阵 $A_{x\times y}$ ,$A_{i,j} = (i-1)x+y$ . 从矩阵中的某个位置出发,每次可向上下左右移动一步,每到一个位置,记录 ...