11.2 Serverless 云函数
敲定需求之后,按照正常的开发流程,下一步是后端同学按照模块出接口。不过本项目我们要全栈开发,实现接口的“自给自足”。我知道大多数前端开发者不懂服务器,不会写接口,所以我们要用一种更简单潮流的开发方式 ——— Serverless 云开发。
什么是 Serverless 云开发?听着很高大上很厉害的样子,但你别被它唬住了。Serverless 是一种无服务器的开发模式,由后端衍生而来,但对前端开发者非常友好,它允许我们在没有服务器的情况下快速产出接口。
没有服务器如何开发接口呢?这就要介绍下 Serverless 的诞生过程。
11.2.1 认识 Serverless
在传统的后端开发模式中,如果要开发一套接口,首先得有一台服务器,然后将后端代码部署到这台服务器上。还要配置域名解析,给到前端 URL 地址,前端才能访问接口。
大多数接口都要与数据库交互,那么还要在服务器上部署数据库。如果是大规模高并发的接口应用,还需要像负载均衡、缓存、消息队列、性能监控等等衍生服务。如果这些都要在服务器上部署的话,一方面成本越来越高,另一方面实施复杂度也在攀升,这把小团队和普通开发者挡在了门外。
于是乎,Serverless 的思想萌芽了:让服务少一点。把通用的复杂的服务单元集中到云上,作为单独的产品供大家购买使用。比如你不会搭建生产级别的数据库,那就买一个云数据库,省去自己在服务器上捣鼓,安全和性能也更有保障。这样服务器上只部署代码,其他服务使用云产品,后端的门槛降低了。
随着后端云原生技术持续发展,一些大佬们开始更大胆的思考:“后端服务都被云产品化,但是后端代码还要在服务器上部署。那么能否让服务再少一点,将后端代码和运行环境也一起打包放在云上,开发者只需要提供要运行的函数,就可以生成 API 接口”。
绕过服务器与代码环境,直接编写要运行的函数,这种开发方式就是 Serverless 云开发。
通过上面的介绍,可以总结出 Serverless 的两种形式:
- BaaS(Backend as a Service):后端即服务。
- FaaS(Function as a Service):函数即服务。
BaaS 是指一个云服务,前面说的云数据库、云存储、云监控等都属于 BaaS。云服务面向后端开发者使用,在接口代码中使用云服务轻松实现高级功能。FaaS 是指一个云函数,云函数不需要使用服务器,只需要在云厂商提供的 Serverless 产品中选择运行环境、创建函数,然后上传函数代码即可。
我们要用到的 Serverless 云开发,特指云函数开发。云函数使开发接口的门槛变得极低,前端开发者未必懂服务器,但多多少少都懂点 Node.js。现在不需要服务器了,我们用 Node.js 写一个包含业务逻辑的函数,基本没什么问题。
在开始开发之前,首先要选择一个云厂商。目前国内最大的云厂商有两个:阿里云、腾讯云。经过本人的实践,腾讯云的云函数产品相对简单,扩展性不高。阿里云的云产品相对完善一些,但也会稍微复杂些。综合考虑,我们选择阿里云。
Node.js + 阿里云云函数,这就是本项目要用到的接口开发方案。
11.2.2 注册阿里云,开通函数计算
阿里云的云函数产品名为“函数计算 FC”。如果您没有使用过阿里云,首先要注册一个阿里云账号,然后再进行实名认证,完成这两步才可以开通函数计算。
- 注册账号并认证
首先搜索进入阿里云官网,然后点击注册,就可以看到注册页面,如图所示:
账号注册支持支付宝扫码注册,这种方式最快捷,可以直接授权获取用户信息。注册时会要求绑定手机号,接收验证码,成功之后会生成一个默认的用户名,此时账号就注册成功了,页面如图所示:
接着再点击“快速实名认证”按钮,跳转到认证页面。认证有两种方式,分别是个人认证和企业认证,我们选择个人认证,然后点击“开始认证”按钮。
页面会继续提示使用支付宝扫码认证,扫码后在手机上同意授权即可快速完成认证。完成后在网页上点击个人头像进入账号中心,在基本信息一栏就可以看到认证结果了。
- 开通函数计算
在网页头部找到搜索框,输入“函数计算”,点击进入函数计算产品页面,如图所示:
点击“管理控制台”进入控制台面板的函数计算入口。控制台是我们的个人工作台,在这里管理我们购买的所有云产品。首次开通函数计算的用户有试用资格,因此进入后页面会弹出试用提示,如图所示。
这里要说明一下,函数计算是按量付费的服务,也就是用多少资源花多少钱,不用就不花钱。函数计算的计费项比较复杂,我们稍后细说,但总的成本要比自己买服务器低。好消息是,函数计算为新用户提供了 3 个月的免费试用期,资源给的很足,三个月内你可以使劲造。
点击“领取试用套餐并开通”按钮,根据提示 0 元下单,我们三个月的试用套餐就到手了。完成之后再次进入控制台,此时会弹框提示创建角色,我们根据引导创建一个默认的角色即可(用于授权)。
至此,函数计算已经开通。可能大家更关心计费问题,免费使用额度超了怎么办?我们看下这三个月的免费额度包含哪些资源:
- 函数调用次数:400 万次。
- 内存使用量:100 万 GB*秒。
- vCPU 使用量:50 万 vCPU*秒。
- GPU 使用量:10 万 GB*秒。
这些资源量足够我们开发使用,不过公网出流量不包含在内。公网出流量就是我们在公网调用接口时产生的流量费,我算了一下,正常使用三个月费用不到 10 块钱,这个也不必担心。具体的资源使用量和产生的费用,可以在控制台中看到到:
11.2.3 创建服务,编写云函数
在函数计算控制台,可以看到左侧有很多子菜单。“概览”菜单主要用来查看函数的使用统计,我们创建和管理云函数主要用到“服务和函数”这个菜单,页面如下:
服务可以看做是函数的一个分组,一个服务包含一个或多个函数,同一个服务下的所有函数共享一些相同的设置。因此创建函数前,首先要创建一个服务。
点击上图中的“创建服务”按钮,在弹出框中输入以下信息:
- 服务名称:blog-server。
- 服务描述:仿掘金博客服务。
- 日志功能:禁用(启用后会记录函数调用结果,会产生费用)。
点击确认创建服务,成功之后可以看到该服务下的函数列表,默认服务中没有函数,如图所示。
点击“创建函数”按钮,我们来创建第一个函数。创建函数的页面如下:
创建函数的选项比较多,我们最终选择和输入的值如下:
- 运行时:自定义运行时。
- 函数名:blog-fun。
- 程序处理类型:处理 HTTP 请求。
- 运行环境:Node.js 16。
- 代码上传方式:使用示例代码。
- 启动命令:npm run start。
- 监听端口:9000。
必填的选项就这么多,其他选项使用默认值即可。下面解释一下部分关键的选项是什么意思。
首先是程序处理类型,因为我们写接口,所以选择处理 HTTP 请求。运行环境不用多说,必须选择 Node.js,让函数在 Node.js 环境下运行(建议统一使用 Node.js 16 这个版本)。
要特别说明的是运行时选项。运行时其实就是设置函数如何运行,常用两个选项:内置运行时、自定义运行时。处理 HTTP 请求时,如果使用内置运行时,相当于定义了一个由 Node.js 直接处理的函数,函数接收请求和响应两个参数,我们直接在函数内编写业务逻辑,然后返回 HTTP 响应。这是真正意义上的云函数。
但是这种方式有两个问题:一是单个函数不适合处理复杂逻辑,只适用于简单功能。二是 Node.js 使用流处理 HTTP 响应,对开发者来说不够友好。所以我们选择自定义运行时。
自定义运行时允许开发者决定代码如何运行,这意味这我们可以使用 Node.js 框架,然后自定义框架启动方式。这种情况下我们用 “运行一个框架” 来代替 “运行一个函数”,此时函数代码就变成了框架代码。
理解这个很重要。云函数并不一定是函数,通过自定义可以使其变成框架、变成脚本或其他形式。我们上面创建的 “blog-fun” 函数,本质上是使用 Express 框架创建了一个 Node.js 应用,应用通过 “npm run start” 命令启动,并监听 9000 端口。
函数创建之后,函数代码可以用在线编辑器打开,页面如下:
可以看到,这是一组标准的 Node.js 代码。在 index.js 中引用了 Express 框架,并定义了简单的 GET 请求和 POST 请求。我们修改代码如下:
const express = require("express");
const app = express();
const port = 9000;
app.get("/*", (req, res) => {
res.send({
code: 202,
message: "[GET]欢迎使用云函数",
});
});
app.post("/*", (req, res) => {
res.send({
code: 203,
message: "[POST]欢迎使用云函数",
});
});
app.listen(port, () => {
console.log(`函数启动并监听 ${port} 端口`);
});
保存后点击“部署代码”按钮,代码会立即更新。再点击“测试函数”按钮,会对该函数发起请求并显示响应结果。当然我们也可以用函数 URL 自行请求,点击“触发器管理” 按钮可以看到 URL 地址,如图所示:
注意:上述地址不可以在浏览器直接打开,可以用接口测试工具(如 Postman)测试。
在 Postman 中分别用 GET 和 POST 方法对函数 URL 地址发起请求,结果如图所示。
可以看到,接口测试结果和我们代码中定义的一致。后续可以继续在线编辑代码,保存后点击部署代码,这样接口就可以快速更新。
为了调试方便和节约流量,大部分人还是会选择本地开发,然后将代码部署到云函数。我们也可以使用 Express 框架在本地创建项目,开发调试,完成后再将代码上传到云函数部署。函数详情页提供了代码上传按钮,如图所示: