本文首发于政采云前端团队博客:结合阿里云 FC 谈谈我对 FaaS 的理解

https://www.zoo.team/article/my-understanding-of-faas

进入主题之前,先从背景简述下最近前端界的热点词汇 Serverless,其实,Serverless 这个概念在其他领域已经提出来很久了。

Serverless

概念

Serverless 直译为无服务器,代表一种无服务器架构(也被称为“无服务器计算”),并不表示不需要物理服务器,而是指不需要关注和管理服务器,直接使用服务即可,其实就是一种服务外包或者说服务托管,这些服务由第三方供应商提供。

具体来说,Serverless 就是指服务端逻辑由开发者实现,运行在无状态的计算容器中,由事件驱动,完全被第三方管理,而业务层面的状态则记录在数据库或存储资源中。

目前国内一些大型公司如阿里、腾讯、滴滴都已经将 Serverless 逐步在业务中落地(案例分享:2020.06.19 ServerlessDays · China Online (https://cloud.tencent.com/developer/salon/live-1224))。

Serverless 与 FaaS 的联系

Serverless = FaaS + BaaS ,是目前界内比较公认的定义:

  • FaaS(Function as a Service):函数即服务

    • 负责服务端业务逻辑场景,需要开发者自己实现,服务的粒度比微服务更小,小到以函数为单位

    • 事件驱动的 Serverless 服务,毫秒级弹性伸缩

    • 无法进行内存或数据共享,是无状态的

    • 无需运维,部署、运维等都由云平台提供

  • BaaS(Backend as Service):后端即服务

    • 负责通用服务场景,不需要开发者自己开发,由云厂商提供,比如数据库、身份验证、消息队列、对象存储等服务

    • 有状态

笔者认为,单看 FaaS 或者 BaaS,都是一种 Serverless ,只是一般我们完整的应用需要两者结合才能实现。

好,下面正式介绍 FaaS。

FaaS

作为一个前端,我们平日里很难接触到服务器、运维方面的操作。假设现在给你一个任务,让你自己开发一个有前后端交互的应用,并从 0 到 1 进行部署,是不是觉得光靠自己根本搞不定,这个任务有点难。

传统应用的部署,我们需要做很多工作:准备服务器、配置环境、购买域名、配置 Nginx、……。应用发布之后,我们还要考虑运维的问题,线上监控,扩缩容,容灾等等等等。

现在,我们运用 FaaS 去开发部署的话,以上都不用考虑,只需要专注于业务逻辑开发即可,因为其它一切都托管给 FaaS 平台帮我们处理了。

概念

FaaS  是无服务器计算的一种形式。通过 FaaS,可以快速构建任何类型的应用和服务,它具有开发敏捷特性、自动弹性伸缩能力、免运维和完善的监控设施。因此:

  • 开发者只需专注于业务逻辑开发,无需管理服务器、运行环境等 IT 基础设施

  • FaaS 平台会为我们准备好计算资源,以弹性、可靠的方式运行我们的代码,实现毫秒级弹性伸缩,轻松应对峰值压力

  • 用户只需根据函数的实际执行时间按量付费

因此,相比传统开发模式,大大提高了开发和交付效率,是未来云服务发展的大趋势。自 2014 年始,在 AWS Lambda 之后,Google、IBM、Microsoft、阿里、腾讯、华为等国内外云厂商相继推出云函数计算平台 FaaS。

快速创建 FaaS 应用

函数计算开发方式有很多种,比如:Fun 工具、函数计算 FC 平台、Serverless VScode、云开发平台。本文借助阿里云函数计算平台(https://fc.console.aliyun.com/fc/overview/cn-shanghai),通过其提供的模版快速创建、部署一个 Web 应用,向大家更清楚地展示 FaaS 是什么。

本文直接基于模版创建,用户也可以选择自己上传应用代码直接部署 Web 应用。

我们选择有前后端交互、数据增删改查等行为的 Todo List 应用,它是一个前后端一体化(前后端代码共属一个项目中开发、调试、部署,高效且节省资源) FaaS 应用。

服务/函数

服务

一个应用可以拆分为多个服务。从资源使用维度出发,一个服务可以由多个函数组成。先创建服务,再创建函数。

可以看到 TodoList 应用部署成功后创建好的服务,我们可以对该服务进行配置、删除、查看指标等操作,还可以对其下的函数进行配置、删除。

函数

函数是系统调度和运行的单位。函数必须从属于服务,同一个服务下可以有多个函数,同一个服务下的所有函数共享相同的设置,例如服务授权、日志配置,但彼此相互独立,互不影响。

函数代码

FaaS 对多种语言都有良好的支持性,比如阿里云支持 Node.js、Python、PHP、Java 等等,开发者可以使用自己熟悉的语言,根据平台提供的函数接口形式编写代码。这也意味着,团队协作时,大家可以利用多种语言混合开发复杂应用。

点击代码执行,可以看到这里有一个在线编辑器,里面就是模板生成的代码,可以在此处进行运行、调试。该应用前端页面用 React 实现,后端服务基于 Node 的 Express 框架。

函数入口

template.yml 是我们的函数信息配置文件,告诉云厂商我们的代码入口函数、触发器类型等操作。

函数入口为 src/index.handler ,即 src/index.js 服务端代码文件中的 handler 方法,该文件代码如下:

const { Server } = require('@webserverless/fc-express')
const express = require('express');
const fs = require('fs');
const path = require('path');
const bodyParser = require('body-parser');// initial todo list
let todos = [{id: '123',text: 'Go shopping',isCompleted: false,},{id: '213',text: 'Clean room',isCompleted: true,},
];const staticBasePath = path.join('public', 'build');const app = express();// index.html
app.all("/", (req, resp) => {resp.setHeader('Content-Type', 'text/html');resp.send(fs.readFileSync('./public/build/index.html', 'utf8'));
});// 静态资源文件:js、css、图片
// static js resources
app.all('/*.js', (req, resp) => {const filePath = path.join(staticBasePath, req.path);resp.setHeader('Content-Type', 'text/javascript');resp.send(fs.readFileSync(filePath, 'utf8'));
});// static css resources
app.all('/*.css', (req, resp) => {const filePath = path.join(staticBasePath, req.path);resp.setHeader('Content-Type', 'text/css');resp.send(fs.readFileSync(filePath, 'utf8'));
});// static svg resources
app.all('/*.svg', (req, resp) => {const filePath = path.join(staticBasePath, req.path);resp.setHeader('Content-Type', 'image/svg+xml');resp.send(fs.readFileSync(filePath, 'utf8'));
});// static png resources
app.all('/*.png', (req, resp) => {const filePath = path.join(staticBasePath, req.path);resp.setHeader('Content-Type', 'image/png');resp.send(fs.readFileSync(filePath, 'utf8'));
});app.all('/manifest.json', (req, resp) => {const filePath = path.join(staticBasePath, req.path);resp.setHeader('Content-Type', 'application/json');resp.send(fs.readFileSync(filePath, 'utf8'));
});// 增删改查对应的api接口
// list api
app.get('/api/listTodos', (req, resp) => {resp.send(JSON.stringify(todos));
});// create api
app.get('/api/createTodo', (req, resp) => {const { todo: todoStr } = req.query;const todo = JSON.parse(todoStr);todos.push({id: todo.id,text: todo.text,isCompleted: todo.isCompleted,});resp.send(JSON.stringify(todos));
});// update api
app.get('/api/updateTodo', (req, resp) => {const { todo: todoStr } = req.query;const targetTodo = JSON.parse(todoStr);const todo = todos.find((todo) => todo.id === targetTodo.id);if (todo) {todo.isCompleted = targetTodo.isCompleted;todo.text = targetTodo.text;}resp.send(JSON.stringify(todos));
});// remove api
app.get('/api/removeTodo', (req, resp) => {const { id } = req.query// TODO: Implement methods to filter todos, filtering out item with the same id// todos = todos.filter();const todosIndex = todos.findIndex((todo) => todo.id === id);if (todosIndex !== -1) {todos.splice(todosIndex, 1);} resp.send(JSON.stringify(todos));
});const server = new Server(app);// 向外暴露了 http触发器入口
// http trigger entry
module.exports.handler = function(req, res, context) {server.httpProxy(req, res, context);
};

可以看到,我们不需要自己起服务,FaaS 平台会为我们管理。这个文件,有两个重要的部分:

  • 1.函数入口 handler,也是 HTTP 触发器入口,下文会详细介绍

// http trigger entry
module.exports.handler = function(req, res, context) {server.httpProxy(req, res, context);
};
  • 2.Web Service 和 API,通过路由调用相应的服务,比如请求路径为"/"时,会返回 Web 应用的 Html 页面;请求"/api/*"时,调用接口返回数据

触发器

前面说过,FaaS 是一种事件驱动的计算模型,即函数的执行是由事件驱动的,没有事件触发,函数就不运行。与传统开发模式不同,函数不需要自己启动一个服务去监听数据,而是通过绑定一个(或者多个)触发器。

触发器就是触发函数执行的方式,我们需要为函数创建指定的触发器。

FaaS 应用的触发器有多种(不同云厂商的触发器会有所区别),但基本都支持 HTTP、对象存储、定时任务、消息队列等触发器,其中 HTTP 触发器是最常见的。

以阿里云函数计算为例,介绍几个代表类型:

触发器类型

名称 描述
HTTP 触发器 1.HTTP 触发器通过发送 HTTP 请求触发函数执行,主要适用于快速构建 Web 服务等场
2.HTTP 触发器支持 HEAD、POST、PUT、GET 和 DELETE 方式触发函数
3.可以通过绑定自定义域名为 HTTP 函数映射不同的 HTTP 访问路径
4.开发人员可以快速使用 HTTP 触发器搭建 Web Service和 API
OSS 触发器(对象存储) 1.OSS 事件能触发相关函数执行,实现对 OSS 中的数据进行自定义处理
日志服务触发器 1.当日志服务定时获取更新的数据时,通过日志服务触发器,触发函数消费增量的日志数据,并完成对数据的自定义加工
定时触发器 1.在指定的时间点自动触发函数执行
API 网关触发器 1.API 网关作为事件源,当有请求到达后端服务设置为函数计算的 API 网关时,API 网关会触发函数的执行。函数计算会将执行结果返回给 API 网关
2.与 HTTP 触发器类似,可应用于搭建 Web 应用。相较于 HTTP 触发器,您可以使用 API 网关进行 IP 白名单或黑名单设置等高级操作

开发者在调试时,如果不配置触发器,也可以使用控制台、命令行工具 或者 SDK 等方式直接调用函数执行。

我们点开 TodoList 的触发器,可以看到创建的 HTTP 触发器,WEB 用户通过 HTTP 请求即可触发函数的执行。

注意这里的提示语:打开链接,会下载一个 Html 附件,这时我们打开,因为找不到静态资源文件,应用不能正常运行。

可以点击自定义域名去用平台为我们创建的临时域名打开:

可以看到,页面和功能都正常了。我们查看、新增、更新、删除,在控制台里可以看到发起的请求和返回结果

HTTP 触发器

该应用 HTTP 触发器的入口函数形式如下:

// http trigger entry
module.exports.handler = function(req, res, context) {server.httpProxy(req, res, context);
};

配置 HTTP 触发器的函数可以通过 HTTP 请求被触发执行。此时函数可以看做一个 Web Server,对 HTTP 请求进行处理,并将处理结果返回给调用端

访问 Html 页面、请求静态资源文件,以及请求接口,都是通过 HTTP 请求去触发相应函数的执行。

可以在这里进行调试:

FaaS 框架

目前市面上已经有一些较为成熟的开源 FaaS 框架,比如 OpenFaaS、Funktion、Kubeless、Fission等等,本文向大家介绍阿里云今年正式发布的 Midway FaaS框架 (https://github.com/midwayjs/midway),它是用于构建 Node.js 云函数的 Serverless 框架,它提供了函数的本地开发、调用、测试整个链路。它可以开发新的 Serveless 应用,也提供方案将传统应用迁移至各云厂商的云函数。阿里内部已经使用一年多了。

我们可以运用脚手架 @midwayjs/faas-cli 提供的能力在本地快速创建、调试、Mock、部署一个 FaaS 应用。Serverless 有一个很大的弊端,就是和云服务商平台强绑定,但是 Midway Serverles 是防平台锁定的,它能一套代码能够运行在不同的平台和运行时之上,Midaway Faas 的部署可以跨云厂商,默认部署到阿里云 FC,我们也可以修改部署到其它平台,如腾讯云 SCF、AWS Lambda。

Midway FaaS 体系也与云工作台进行了结合,使用了和本地同样的能力,这里选择登录 阿里云开发平台 (https://workbench.aliyun.com/application),用示例库模版再次创建一个 TodoList 应用进行演示,只不过这个是用 Midway FaaS 构建的。

代码目录结构可以简单抽取为:

|-- src
|  |-- apis //函数代码
|    |-- config //针对不同环境创建配置文件
|    |-- configuration.ts //扩展能力配置
|    |-- index.ts // 函数代码入口文件,里面包括多个函数
|  |-- components // 前端组件
|  |-- index.tsx // 前端页面入口文件(该应用前端基于React,若是Vue,则是App.vue)
|-- f.yml // 函数信息配置文件

f.yml 配置文件

service: serverless-hello-world// 服务提供商
provider:name: aliyunruntime: nodejs10 //运行时环境及版本信息// 函数具体信息(包括函数入口、触发器等等)
functions:render:handler: render.handler events:- apigw:path: /*list:handler: todo.list events:- apigw:path: /api/listupdate:handler: todo.updateevents:- apigw:path: /api/updateremove:handler: todo.removeevents:- apigw:path: /api/removeadd:handler: todo.addevents:- apigw:path: /api/add// 构建的配置信息
package:include:- build //打包目录artifact: code.zip //打包名称

函数代码中一个函数对应一个 API 接口:

安装依赖后,我们 npm run dev,阿里云为我们创建了一个临时域名用于调试:

可以看到请求的这些资源和接口数据:

一键部署,非常方便。

收费标准

传统应用我们的服务是一直占用资源的,而 FaaS 在资源空闲时不收费,按需付费,可以大大节省开支。

收费标准:

  • 调用函数次数

  • 函数运行时间

因为每月都有免费额度,所以在个人日常使用时基本不需要付费。

(PS:但还是要特别注意,部署的应用不用时一定要及时下线,否则可能会收取费用,还有开通的服务、功能也一定要仔细留意一下收费标准,比如可能想解决冷启动的问题,会开通预留实例功能,如果我们不用的话,一定要注意手动释放,否则即使它没有执行任何请求,也会从启动开始不断收费,费用可不小)

冷启动

再说说 FaaS 目前备受关注的一个问题——冷启动

FaaS 中的函数首次调用更新函数或长时间未调用时重新调用函数时,平台会初始化一个函数实例,这个过程就是冷启动,平均耗时在几百毫秒。

延迟问题

FaaS 因为冷启动,不能立即调用函数,调用延迟会给应用性能带来影响,针对冷启动的延迟问题,各大云服务商非常关注,正在想办法不断优化。

与冷启动相呼应的是热启动,热启动指函数调用时不用重新创建新的函数实例,而是直接复用之前的函数实例。因为 FaaS 函数若在一段时间内没有被事件触发运行,云服务商就会回收运行函数的容器资源,销毁函数实例,所以,在未被回收的这段时间内再次调用函数就是热启动;销毁后,重新创建就是冷启动。

延迟原因

冷启动具体做了哪些操作呢?以阿里云为例,大致包括了调度实例、下载解压代码、启动容器、启动运行时,这一过程结束后,函数才开始执行。所以冷启动的启动消耗时间受到很多因素的影响:

  • 编程语言

    有专门研究对比,不同语言的冷启动时间不同

  • 代码大小

    这个过程在冷启动过程中相对比较耗时,可能几十毫秒,也可能几秒,看代码体积大小

  • 容器创建

    这个过程的耗时取决于云服务商

  • 配置等

如何优化

各大云厂商都已经有了一些优化方案的最佳实践,需要开发者和云厂商共同努力:

  • 减少代码体积:

    • 开发者可以通过精简代码,删除无用依赖,加速下载函数代码过程

    • 比如腾讯云对代码做了两级的缓存,可以有效降低下载代码时间

  • 资源复用,缩短函数执行时间

  • 选择冷启动时间较少的语言

  • 选择合适的内存:函数内存越大,冷启动表现越优

  • 避免不必要的配置

  • 降低冷启动频率

    • 使用定时触发器定时访问函数,这样可以防止函数实例一段时间没被使用被销毁

    • 使用 initializer 函数入口,函数计算会异步调用初始化接口,消除初始化用户代码的时间

  • 预留实例

执行时长

FaaS 还有一个局限性,就是平台会限制函数的执行时间,超出时间后执行代码的进程会被强行销毁,所以 FaaS 不适合长时间运行的应用。例如 AWS Lambda 函数不允许运行超过 15 分钟(以前只有 5 分钟),如果超过就会中断。使用时,应该根据自己的预期执行时间来设置超时值,防止函数的运行时间超出预期,并且建议调用函数的 Client 端的 timeout 要稍稍大于函数设置的 timeout,这样才能防止执行环境不会意外退出。

FaaS 工作流程

相信大家读到这里,应该差不多可以明白 FaaS 的工作流程了,我们总结一下:

  • 开发者编写函数代码,可以在线编辑或者本地上传,完成后,FaaS 平台为我们部署应用,创建函数服务

  • 客户端通过设置的触发器,通知函数服务

  • 若存在函数实例,则直接在该执行环境中调用函数;没有,则先经过冷启动(调度实例、下载代码、启动实例、启动运行时),再执行函数

  • 函数根据用户请求量动态扩容响应请求,将内容返回给用户。函数执行完后,若一段时间内无事件触发,函数实例就会被销毁,FaaS 应用快速缩容到 0

对前端的影响

Serverless 现在这么热,它对前端到底有什么影响呢?

整个实践下来发现,FaaS 帮我们前端扩展了能力边界,作为前端,我们自己一个人也能快速完成前后端开发以及部署工作,完全不用关心服务器以及运维方面我们不擅长的问题。前端也有机会参与服务端业务逻辑开发,更深入业务,创造更大的价值。

结语

本文结合阿里云 FC、Midway FaaS 框架快速创建 FaaS 应用的实践,向大家展示了什么是 FaaS,FaaS 的工作流程,优缺点,展现了 FaaS 颠覆传统开发模式的魅力。现在 FaaS 的应用场景非常广泛,Web 应用及小程序等移动应用、AI 及机器学习、物联网、实时数据处理、……、等等。Serverless 时代,生产效率大大提高,每个人都有更多机会创造无限可能,让我们一起为未来加油!

参考文章

Serverless Handbook——无服务架构实践手册:https://jimmysong.io/serverless-handbook/concepts/what-is-serverless.html

阿里云函数计算使用文档:https://help.aliyun.com/document_detail/52895.html?spm=a2c4g.11186623.6.542.979d10f394oRpI

Midway Serverless 使用文档:https://www.yuque.com/midwayjs/faas

腾讯云函数计算冷启动优化实践:https://www.tengxunyun8.com/953.html

Serverless Architectures(译文)—(Martin Fowler):https://www.jianshu.com/p/745896ccf145

相关推荐

  • 万字长文之 Serverless 实战详细指南

最后

  • 欢迎加我微信(winty230),拉你进技术群,长期交流学习...

  • 欢迎关注「前端Q」,认真学前端,做个专业的技术人...

点个在看支持我吧

结合阿里云 FC 谈谈我对 FaaS 的理解相关推荐

  1. 【阿里云原生应用】使用阿里云FC函数计算完成阿里云CDN目录刷新

    目录 需求背景 关于OSS静态网站托管 OSS静态网站托管之CDN缓存刷新问题 开始着手解决 CDN-刷新预热 预热刷新API SDK技术选型 基础流程 FC函数计算 创建函数 Python HTTP ...

  2. 阿里云函数计算(fc)使用体验

    为什么会有无服务(Serverless)构架 经过最近几年容器化和Devops的发展,程序员已经变得越来越"懒惰"了--对于部署环境,开发能不管理尽量不管理.于是乎,Docker, ...

  3. 云原生应用架构转型不好做?阿里云让你一步到位!

    简介:Gartner于 2019 年发布报告表示:云原生时代已经到,在未来三年中将有 75% 的全球化企业使用容器化的应用.云原生具有诸多优势,如系统弹性带来用户体验提升.研发效能提升.低成本运维或免 ...

  4. 云原生应用架构转型不好做?阿里云这个平台让你一步到位!

    云原生实践带来的挑战  阿里云云原生为企业提供了完善的容器服务.函数计算.微服务体系.中间件体系.每个服务都有伸缩性.弹性和组合性,通过产品选择或组合搭建,能轻松完成应用与运行环境解耦,和传统应用研发 ...

  5. 对话阿里云李飞飞:云原生数据库的时代来了

    [导语]以中国人民大学经济信息管理系首任系主任萨师煊于 1978 年在黑板上首次写下"数据库"三个字为开端,中国数据库在 Oracle.DB2.Informix 等主流产品笼罩的市 ...

  6. 阿里云张建锋:工业互联网不是工业自动化

    [CSDN编者按]"数据,正在成为新的生产要素",刚刚带领阿里云参与"上千亿项目"的阿里巴巴集团CTO.阿里云智能总裁张建锋,在广东省大数据开发者大会暨2019 ...

  7. 阿里云Landing Zone系列--2 资源目录之--多账号

    系列文章目录 第一章 阿里云云治理中心使用 补充-业务场景说明 第二章 资源目录之–多账号 文章目录 系列文章目录 前言 一.资源目录是什么? 二.方案学习 1. 学习途径-阿里云最佳实践 2.方案要 ...

  8. SIM7600连接阿里云

    Sim7600连接阿里云记录 首先通过sim7600连接常规mqtt服务器,使用sim76xx的MQTT指令正常连接成功. 这里用的工具是通讯猫mqtt工具,首先用电脑端软件连接mqtt服务器正常,并 ...

  9. 阿里云服务器,腾讯云服务器,华为云服务器被攻击了怎么办?

    国有云里边阿里云的用户是最多的,经常会遇到有用阿里云的客户来咨询我服务器被进犯的问题.总的来说呢原因也是很简略的,阿里云的服务器都是只要5G的自带防护都是一碰就死,进犯本钱低,所以很简略被进犯.那么咱 ...

最新文章

  1. 95E Lucky Country
  2. Struts2标签库常用标签(转)
  3. 一天搞定CSS:盒模型content、padding、border、margin--06
  4. python atm作业详解_python day4 作业 ATM
  5. robot连接mysql_robot连接mysql - autocar - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...
  6. 【结论】取石子游戏(jzoj 1211)
  7. LeetCode 848. 字母移位(前缀和+取模)
  8. ICLR 2021 | 腾讯 AI Lab 入选论文
  9. java int数组任何数之间间隔不能对于指定数,内付极速排序
  10. Qt总结之二十三:QByteArray与char、int、float(及其数组)之间的互相转化
  11. 201903版的idea markdown无法预览的问题
  12. python电影院售票系统毕业设计开题报告
  13. NBU备份恢复Vmware
  14. 通过 SiteServer CMS 推进政府网站集约化、集群化建设
  15. Flask的Jinjia2模板
  16. Mac屏幕分辨率如何更改?
  17. 这回稳了!广和通4G低功耗摄像头解决方案全新来袭
  18. sr550服务器配置硬盘,【联想SR550配置】联想SR5502颗服务器配置-ZOL中关村在线
  19. 常用开源库收集+网站收集
  20. CS专业本科期间最重要的能力是什么?

热门文章

  1. Android谷歌地图地理编码,谷歌地图API地理编码多个地点
  2. 计算机基础知识在教学的应用,计算机基础知识中项目教学法的应用
  3. java读取apk、ipa包名、版本名、版本号等信息
  4. Veritas NetBackup8.1.1客户端安装
  5. python按日期爬取b站弹幕 2.0版
  6. 揭秘中国商品期货市场的9大重要因子
  7. Travis CI 简介
  8. uniapp 读取手机 通讯录 分组
  9. 工资买不起薪iphone,你还不跳槽?
  10. c语言课程设计报告停车系统,停车场管理系统C语言课程设计