# 4. OpenFaaS组件

## 基础组件

（**重要组件**加粗）：

* **Gateway 网关**
* **Provider** 应用编排调度器提供方（我的理解）
* **WatchDog** 函数监控
* Queue-worker 消息队列服务

{% hint style="info" %}
Queue-worker 消息队列服务，用于异步函数
{% endhint %}

其他组件：

* Promethus 用于监控
* AlterManager&#x20;
* Grafana 图表可视化
* UI界面，Gateway内置的
* 函数商店

以下依次分析基础组件：

### **Gateway 网关**

* 为函数调用提供路由，起到一个基础转发的功能
* 内置UI界面，可访问函数商店
* Promethus收集监控指标
* 接受AlterManager通知，自动扩缩容

![](https://1205234865-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lg5jN2bbDNytG0ZEOWR%2F-LjQ8geHEj_Ia58fkCnV%2F-LjQJI5MW31HQ8lWMQww%2Fof-conceptual-operator.png?alt=media\&token=55739789-a978-48cd-ae8e-37d54b7b55dd)

在上面的图中，

* 用户通过`faas-cli`、UI或REST API请求访问OpenFaaS的Gateway网关 `/function/<name>`、`/ui`;
* 请求会被转发到Provider，如图中的Kubernetes；
* Provider会调用函数，具体是通过Watchdog调用forked process
* Prometheus从Gateway收集监控数据
* AlertManager根据设置的报警规则，通知Gateway `/system/alert`自动扩缩容。
  * 函数可以通过使用`faas-idler`或REST API再缩容到0。

除了自动扩缩容，也可以手动调用扩缩容API。

### Provider

目前官方支持的Provider有：

* **faas-netes**- Kubernetes provider
* **faas-swarm** - Docker Swarm provider

其他参考<https://github.com/openfaas/faas/blob/master/community.md#openfaas-providers>。

OpenFaaS是少数支持Nomad的FaaS运行时

![FaaS运行时对比](https://1205234865-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lg5jN2bbDNytG0ZEOWR%2F-LjUbfuwqW2uc-4ivaJL%2F-LjUboDigWOmghXFBi18%2FFaaS%E8%BF%90%E8%A1%8C%E6%97%B6%E5%AF%B9%E6%AF%94.png?alt=media\&token=77b0675c-a7b5-4247-866e-93b8afbcbf95)

Provider封装提供的接口应该有：

* List/Delete/Create 函数
* **设置函数副本数**
* **获取函数副本数**

部署函数的细节也是通过Provider提供的接口完成的

![部署函数](https://1205234865-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lg5jN2bbDNytG0ZEOWR%2F-LjUUd-CRJ07YzjBOuIv%2F-LjUZR9YkklzMVjU7vrg%2Fopenfaas_deploy.png?alt=media\&token=f2e6b409-afb2-4a42-9b42-51b4f36e24ac)

![调用函数](https://1205234865-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lg5jN2bbDNytG0ZEOWR%2F-LjUUd-CRJ07YzjBOuIv%2F-LjUZThQ27b-Y_tPQx8L%2Fopenfaas_invoke.png?alt=media\&token=b5f1414f-5b5c-4c12-842f-a674b7400c30)

### **WatchDog** 函数监控

经典的WatchDog，如下，每个请求都会fork一个函数进程执行。经典的WatchDog模式有很高的可移植性，但性能不高。

![经典的WatchDog](https://1205234865-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lg5jN2bbDNytG0ZEOWR%2F-LjUUd-CRJ07YzjBOuIv%2F-LjUZIs19OdeE0cBkyOI%2Fopenfaas_watchdog.png?alt=media\&token=07e3dc22-18e2-46a8-9027-f22d278be3d8)

新的WatchDog项目of-watchdog，具有更高的性能，默认http模式。

![of-watchdog模式](https://1205234865-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lg5jN2bbDNytG0ZEOWR%2F-LjUUd-CRJ07YzjBOuIv%2F-LjU_-AANj5O9TspY5m9%2Fvarious%20modes%20for%20the%20of-watchdog%20component.png?alt=media\&token=47b1c529-85fb-403d-8af4-c2a02a259fab)

此版本的监视程序为高吞吐量带来了新功能，并允许重用昂贵的资源，如数据库连接池或机器学习模型。主要区别在于能够在调用之间保持函数进程温暖，可以重复使用相同的进程来抵消fork进程时的延迟。

### Queue-worker

Queue-worker组件提供消息队列服务，用于**异步**地处理事件。目前Kafaka还在PR中。

Queue-worker使用NATS和NATS Streaming。Gateway是发布者，Queue-worker是订阅者。

{% hint style="info" %}
**NATS**消息传递支持在计算机应用程序和服务之间交换的数据分段为消息。这些消息由主题解决，不依赖于网络位置。这在应用程序或服务与底层物理网络之间提供了一个抽象层。数据被编码并构成消息并由发布者发送。该消息由一个或多个订户接收，解码和处理。&#x20;

NATS使程序可以轻松地跨不同环境，语言，云提供商和内部部署系统进行通信。客户端通常通过单个URL连接到NATS系统，然后订阅或发布主题的消息。通过这种简单的设计，NATS允许程序共享公共消息处理代码，隔离资源和相互依赖性，并通过轻松增加处理消息量进行扩展，无论是服务请求还是流数据。

NATS核心提供最多一次的服务质量。如果订户没有收听主题（没有主题匹配），或者在发送消息时未激活，则不会收到消息。这与TCP/IP提供的保证级别相同。默认情况下，NATS是一种**即发即弃**的消息传递系统。如果您需要更高级别的服务，您可以使用**NATS Streaming**或通过经过验证的可扩展参考设计为客户端应用程序构建额外的可靠性。
{% endhint %}

![发布订阅](https://1205234865-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lg5jN2bbDNytG0ZEOWR%2F-LjUUd-CRJ07YzjBOuIv%2F-LjUbQvm6yC4XbCb3vu0%2FNATS_%E5%8F%91%E5%B8%83%E8%AE%A2%E9%98%85.png?alt=media\&token=85305c4f-a54c-4ed2-9a5d-c1d6e3626f79)

同步异步的区别[官网](https://docs.openfaas.com/reference/async/)和之前的文档，还是[之前的文档](https://github.com/openfaas/faas/blob/master/guide/deprecated/asynchronous.md)讲地清楚。

#### 同步异步的区别

| 项      | 同步                 | 异步                             |
| ------ | ------------------ | ------------------------------ |
| 路由     | `/function/<name>` | `/async-function/<name>`       |
| 函数执行   | 等待结果               | 立即返回`202`即时响应码                 |
| 函数调用结束 | 明确知道处理结果           | 在Queue-worker中调用函数，默认情况下处理结果丢弃 |

![同步](https://1205234865-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lg5jN2bbDNytG0ZEOWR%2F-LjUciseEB4OSJl6likQ%2F-LjUcldJ7qhqbac7zkDU%2Fopenfaas_%E5%90%8C%E6%AD%A5.png?alt=media\&token=e68555b9-e2b6-43b8-bf3b-3294bd138fda)

![异步](https://1205234865-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lg5jN2bbDNytG0ZEOWR%2F-LjUciseEB4OSJl6likQ%2F-LjUcwPuW2tRTsVdmw5Y%2Fopenfaas_%E5%BC%82%E6%AD%A5.png?alt=media\&token=b584602d-61d2-4a27-8841-51699242cae3)

异步有一步入队`dequeue`的过程，然后在queue-worker中执行函数。异步通常基于事件、回调函数机制。

在异步请求的headers中，加入`X-Callback-Url`可以在执行完成后回调通知。回调的URL请求还会设置其他[请求头](https://docs.openfaas.com/reference/async/#callback-request-headers)，标识哪一条异步请求、异步请求的处理状态、时间。

![回调](https://1205234865-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lg5jN2bbDNytG0ZEOWR%2F-LjUciseEB4OSJl6likQ%2F-LjUdJlQEJyEYaKcK_L6%2Fopenfaas_%E5%BC%82%E6%AD%A5%E5%9B%9E%E8%B0%83.png?alt=media\&token=e6a1e8c2-5d7b-43c4-953b-c309a2970c7f)

### AlertManager

AlterManager触发自动扩缩容的步骤：

* 获取现有副本数
* 计算新的副本数
* 调用Provider接口，设置新的副本数。如**faas-netes** 调用Kubernetes的API

### 参考：

* gateway <https://docs.openfaas.com/architecture/gateway/>
* OpenFass 介绍及源码分析 <https://www.youtube.com/watch?v=bZtgrAVR9HQ>
