本篇主要演示腾讯云serverless部署
Web 函数管理
Web 函数运行原理如下图所示:
用户发送的 HTTP 请求经过 API 网关后,网关侧将原生请求直接透传的同时,在请求头部添加了网关触发函数时需要的函数名、函数地域等内容,并一起传递到函数环境,触发后端函数执。
函数环境内,通过内置的 Proxy 实现 Nginx 转发,并去除头部非产品规范的请求信息,将原生 HTTP 请求通过指定端口发送给用户的 Web Server 服务。
用户的 Web Server 配置好指定的监听端口9000和服务启动文件后部署到云端,通过该端口获取 HTTP 请求并进行处理。
Web 函数请求限制
- Web 函数只能通过 API 网关调用,不支持通过函数 API 接口触发。
- 在 Response headers 中有以下限制:
- 所有 key 和 value 的大小不超过4KB。
- body 的大小不超过6MB。
- 部署您的 Web 服务时,
必须监听指定的 9000 端口
,不可以监听内部回环地址127.0.0.1
。 - 目前 HTTP 请求 Header 里的 Connection 字段不支持自定义配置。
启动文件作用
scf_bootstrap 为 Web Server 的启动文件,保证您的 Web 服务正常启动并监听请求。除此之外,您还可以根据需要在 scf_bootstrap 中自定义实现更多个性化操作:
- 设定运行时依赖库的路径及环境变量等。
- 加载自定义语言及版本依赖的库文件及扩展程序等,如仍有依赖文件需要实时拉取,可下载至 /tmp 目录。
- 解析函数文件,并执行函数调用前所需的全局操作或初始化程序(如开发工具包客户端 HTTP CLIENT 等初始化、数据库连接池创建等),便于调用阶段复用。
- 启动安全、监控等插件。
使用前提
- 需具有可执行权限,请确保您的
scf_bootstrap
文件具备777或755权限,否则会因为权限不足而无法执行。 - 能够在 SCF 系统环境(CentOS 7.6)中运行。
- 如果启动命令文件是 shell 脚本,第一行需有
#!/bin/bash
。 - 启动命令必须为绝对路径
/var/lang/${specific_lang}${version}/bin/${specific_lang}
,否则无法正常调用,详情请参见 标准语言环境绝对路径。 - 建议使用监听地址为
0.0.0.0
,不可以使用内部回环地址127.0.0.1
标准语言环境绝对路径
常见 Web Server 启动命令模版
serverless fromework及控制台部署
serverless文档 https://www.serverless.com/cn/framework/docs/
1. 控制台部署
部署koa2管理端接口
官方demo https://github.com/tencentyun/serverless-demo/blob/master/WebFunc-KoaDemo/src/app.js
仓库关联GitHub,提交git代码自动更新
2. 命令行部署-Serverless Framework方式
云函数和serverless的区别
Serverless Framework
是Serverless
公司推出的一个开源的Serverless
应用开发框架。Serverless Framework
是由Serverless Framework Plugin
和Serverless Framework Components
组成。Serverless Framework Plugin
实际上是一个函数的管理工具,使用这个工具,可以很轻松的部署函数、删除函数、触发函数、查看函数信息、查看函数日志、回滚函数、查看函数 数据等。简单的概括就是serverless
其实就云函数的集合体,使用serverless
后我们创建的云函数不需要手动去创建触发器等操作。- 官方地址
serverless
官网地址serverless
中文官网github
地址
Serverless Framework应用场景
什么场景下需要使用
serverless
,而不是使用云函数,其实在实际开发过程中,我们都是使用serverless
而不去使用云函数,毕竟云函数的使用场景受限,或者说比较基础。打一个简单的比方,在写js
操作dom
的时候,你会选择用原生js
还是会使用jquery
一样的比喻。
- 基于云函数的命令行开发工具
- 通过
Serverless Framework
,开发者可以在命令行完成函数的开发、部署、调试。还可以结合前端服务、 API 网关、数据库等其它云上资源,实现全栈应用的快速部署。
- 通过
- 传统应用框架的快速迁移
Serverless Framework
提供了一套通用的框架迁移方案,通过使用Serverless Framework
提供的框架组件(Egg/Koa/Express
等,更多的框架支持可以参考),原有应用仅需几行代码简单改造, 即可快速迁移到函数平台。同时支持命令行与控制台的开发方式。
使用
serverless
命令创建第一个应用
全局安装命令
代码语言:javascript复制npm install -g serverless
serverless -v
创建项目
代码语言:javascript复制在电脑的一个空目录下运行命令
serverless
根据提示选择你要创建的模板
控制台输入
serverless
选择对应的模板
部署上线
代码语言:javascript复制serverless deploy
serverless.yml配置详情
https://github.com/serverless-components/tencent-http/blob/master/docs/configure.md
部署上线后可以在这里查看你的项目
img
测试部署的项目
img
删除部署的项目
img
3. 在vscode中配置插件来开发serverless
在vscode
上安装插件
img
在vscode
安装后插件登录并且拉取应用
img
关于登录账号及密钥查看地址
远程拉取代码
img
下载后的代码如果想上传也可以直接上传的
img
WebIDE创建云函数实践
serverless部署前端项目
建议使用 Serverless Framework CLI,可快速部署本地云函数
- 使用命令生成
vue
项目文件 - 直接将代码推送到云端就可以
- 也许你会好奇,我们正常的
vue
项目部署都要先npm run build
,然后将打包后的dist
目录传到服务器上的nginx
静态目录下,这样才能访问 - 注意前端的项目部署都是存储到
oss
中的 - 使用
serverless
默认生成的项目是vue2
版本的,如果你要部署vue3
的项目需要手动构建
# serverless.yml文件
component: website
name: vue-starter
app: vue-demo-70a4c710
inputs:
src:
src: ./src
# 配置了这个hook每次发布的时候会先build
hook: npm run build
dist: ./dist
bucketName: my-vue-starter
protocol: https
手动构建一个vue3
的项目
- 参考文档
- 使用脚手架创建一个
vue3
项目 - 初始化一个
serverless.yml
文件
serverless init website-starter --name example
将这个
serverless.yml
文件复制到vue3
项目中
简单的修改下
代码语言:javascript复制component: website
name: websiteDemo
app: vue3-demo-6cb9842a
inputs:
src:
src: ./src
hook: npm run build
dist: ./dist
region: ap-guangzhou
bucketName: my-website-starter
protocol: https
部署上线
serverless deploy
手动部署react
项目
代码语言:javascript复制手动创建一个
react
项目
npx create-react-app react-demo --template typescript
代码语言:javascript复制在
react
根目录下创建一个serverless.yml
的文件
component: website
# 这里修改下
name: react-starter
# 这里修改下
app: reactDemo
inputs:
src:
src: ./src
hook: npm run build
# 这里要根据你打包后的目录
dist: ./build
# 这个定义下
bucketName: my-react-starter
protocol: https
推送到云端
serverless deploy
使用静态文件托管来部署前端项目
- 先本地根据项目命令打包好
- 在云产品中选择静态文件托管
img
- 直接将上传你打包后的代码
img
在serverless中连接mysql
数据库的准备
使用
serverless
开发与我们自己使用云服务器服务器ECS
不一样的,因为我们不能在serverless
上安装软件(我们不能安装第三方的mysql
、docker
、redis
)等软件,因此我们在使用serverless
开发的时候,如果我们项目中使用到了比如:mysql
、redis
、rabbitMQ
、RocketMQ
类的我们就需要自行解决。下面介绍几种方式
- 自己有一台备用的云服务器
ECS
,我们在上面安装了需要的软件,对外提供了IP
或者域名,在安全组中开放了端口号以供我们在serverless
中使用。其实如果你自己有云服务器ECS
可能就不会考虑使用serverless
来开发了 - 单独使用第三方付费或者按量收费的数据库,比如:
- 阿里云的云数据库RDS MySQL
- 腾讯云的数据库云数据库
- 使用腾讯云官方自带的有免费额度的
NoSQL
数据库参考文档,本训练营会介绍如何使用,但是在项目中不会使用。 - 我在自己的服务器上使用
docker
搭建了一个mysql8
版本的数据库,以供大家学习使用,自己根据自己的名字来在上面创建自己的数据库。大家自行保存地址,如果自己有服务器的,可以自己服务器上搭建,就不需要用我这个
# ip地址
8.129.234.99
# 用户名
root
# 密码
123456
在serverless
中连接mysql
本案例只是测试官方案例连接数据库,不涉及什么知识点,根据自身条件选择是否跳过
在函数服务中选择
mysql
数据库模板来创建数据库云函数应用。注意选择的语音和区域
img
代码语言:javascript复制在自己的数据库中创建数据库及数据表
-- 创建数据表sql
CREATE TABLE `account` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`username` varchar(50) NOT NULL COMMENT '用户名',
`password` varchar(100) NOT NULL COMMENT '密码',
`created_at` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
`updated_at` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
`deleted_at` timestamp(6) NULL DEFAULT NULL COMMENT '软删除时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 插入几条数据sql
insert into account(username, password) values('admin', '123456');
insert into account(username, password) values('张三', '123456');
打开云函数的代码管理修改数据库的连接配置
img
代码语言:javascript复制进入代码编辑界面的函数代码编辑代码
function wrapPromise(connection, sql) {
return new Promise((res, rej) => {
connection.query(sql, function(error, results, fields) {
if (error) {
rej(error)
}
res(results)
})
})
}
exports.main_handler = async (event, context, callback) => {
const mysql = require('mysql');
const connection = mysql.createConnection({
host: '8.129.234.99', // 云数据库实例ip地址
user: 'root', // 云数据库用户名,如root
password: '123456', // 云数据库密码
database: 'serverless_nest' // 数据库名称
});
connection.connect();
// 你需要查询的sql文件
const querySql = `SELECT * from account`
// 查询结果
let queryResult = await wrapPromise(connection, querySql)
connection.end();
return queryResult
}
修改完成后点击部署和测试
img
出现下面界面表示你已经在云函数中连接mysql
成功了
img
如果你想在浏览器上测试访问,可以点击触发管理
img
云开发与serverless的区别
Serverless Framework
是无服务器应用框架,提供将云函数SCF
、API
网关、对象存储COS
、云数据库DB
等资源组合的业务框架,开发者可以直接基于框架编写业务逻辑,而无需关注底层资源的配置和管理。- 云开发(
Tencent CloudBase,TCB
)是腾讯云提供的云原生一体化开发环境和工具平台,为开发者提供高可用、自动弹性扩缩的后端云服务,包含计算、存储、托管等serverless
化能力,可用于云端一体化开发多种端应用(小程序、公众号、Web
应用、Flutter
客户端等),帮助开发者统一构建和管理后端服务和云资源,避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。 - 二者最大的区别是:给开发者使用的平台支持不一样,云开发支持web端、QQ、微信小程序级静态网站托管等这些平台服务。
使用云开发创建一个nest
项目
在产品中选择云开发产品
img
创建一个项目,注意点:这里要选择好区域,下次创建了项目,区域不一样,可能项目就看不到
img
使用模板创建
img
查看自己创建应用并且访问
img
使用脚手架的方式创建
全局安装脚手架包官方地址
代码语言:javascript复制npm i -g @cloudbase/cli
测试安装是否成功
代码语言:javascript复制cloudbase -v
登录
代码语言:javascript复制cloudbase login
本地创建项目
代码语言:javascript复制tcb new <appName> [template]
# 比如
tcb new nest-cloundbase nest-starter
选择自己已经创建的环境,如果没有就 创建新环境,这时候会打开浏览器
img
本地打开项目并且安装依赖包
代码语言:javascript复制npm run dev
部署到线上
代码语言:javascript复制npm run deploy
img
在云开发中使用NoSQL
在面板上创建一个NoSQL
的数据库,参考地址
img
在项目中安装连接数据库的SDK
参考文档
npm install @cloudbase/node-sdk
初始化数据库连接参考地址
代码语言:javascript复制import cloudbase from '@cloudbase/node-sdk';
// 注意以下几个参数是必填的,文档上说的是非必填
const app = cloudbase.init({
secretId: 'xx',
secretKey: 'yy',
env: 'xx',
// 根据你创建的区域来写,目前只有上海(ap-shanghai)、广州(ap-guangzhou)
region: 'ap-shanghai'
})
// 1. 获取数据库引用
const db = app.database();
关于获取secretId
、secretKey
、env
的地址
env
的获取地址
img
secretId
和secretKey
获取
img
- 点击
test
用户进入
img
根据文档,我们将插入一条数据(同样先忽视类型检测)
代码语言:javascript复制async createAccount(data: any): Promise<any> {
const res = await db.collection('account')
.add({
...data,
});
return res;
}
环境变量的配置
本地开发环境变量的配置
- 安装依赖包
npm install dotenv
npm install @types/dotenv -D
代码语言:javascript复制在项目根目录下创建一个
.env
的文件用来存储一些敏感信息
PORT=7000
SECRET_ID = AKIDMfCxx2stVYNUx
SECRET_KEY = d3C7pxxxv1VqiMrBHS
ENV = serverlxxim00f1a872
REGION = ap-guangzhou
在应用中使用使用环境变量的值
代码语言:javascript复制const app = cloudbase.init({
secretId: process.env.SECRET_ID,
secretKey: process.env.SECRET_KEY,
env: process.env.ENV,
// 根据你创建的区域来写,目前只有上海(ap-shanghai)、广州(ap-guangzhou)
region: process.env.REGION
})
我是程序员小月,更多干货在公号「前端进阶之旅」分享