- 一、什么是 Serverless
- 二、编写你的第一个 Serverless 应用
- 三、Serverless 应用是怎么运行的
- 四、如何提高应用开发调试和部署效率
- 五、serverless 应用
- 阿里云函数计算
- 腾讯云函数
- 使用 vercel 部署你的应用-推荐
- 六、场景案例
2.1 内容管理系统的架构设计
在进行架构设计前,你要明确系统的需求。对于一个内容管理系统,最核心的功能(也是这一讲要实现的功能),主要有这样几个:
- 用户注册;
- 用户登录;
- 发布文章;
- 修改文章;
- 删除文章;
- 查询文章。
这 6 个功能分别对应了我们要实现的 Restful API。为了方便统一管理 API,在 Serverless 架构中我们通常会用到 API 网关,通过 API 网关触发函数执行,并且基于 API 网关我们还可以实现参数控制、超时时间、IP 黑名单、流量控制等高级功能。
对于文章管理相关的 Restful API,用户发布文章前需要先登录,你已经知道在 Serverless 中可以用 JWT 进行身份认证,咱们的管理系统中的登录注册功能也将沿用上一讲的内容。
在传统的 Serverful 架构中,通常会用 MySQL 等关系型数据库存储数据,但因为关系型数据库要在代码中维护连接状态及连接池,且一般不能自动扩容,并不适合 Serverless 应用,所以在 Serverless 架构中,通常选用表格存储等 Serverless NoSQL 数据来存储数据。
基于 JWT 的身份认证方案、数据存储方案,我们可以画出 Serverless 的内容管理系统架构图:
- 图中主要表达的意思是: 通过 API 网关承接用户请求,并驱动函数执行。每个函数分别实现一个具体功能,并通过 JWT 实现身份认证,最后表格存储作为数据库。
- 其中,数据库中存储的数据主要是用户数据和文章数据。假设用户有 username(用户名) 和 password(密码) 两个属性;文章有
article_id
(文章 ID)、username
(创建者)、title
(文章标题)、content
(文章内容)、create_date
(创建时间)、update_date
(更新时间)这几个属性
接下来,你可以在表格存储中创建对应的数据表(你可以在表格存储控制台创建,也可以直接用我提供的这段代码进行创建):
// index.js const TableStore = require("tablestore"); // 初始化 TableStore client const client = new TableStore.Client({ accessKeyId: '<your access key>', accessKeySecret: '<your access secret>', endpoint: "https://serverless-app.cn-shanghai.ots.aliyuncs.com", instancename: "serverless-cms", }); /** * 创建 user 表 * * 参考文档: https://help.aliyun.com/document_detail/100594.html */ async function createUserTable() { const table = { tableMeta: { tableName: "user", primaryKey: [ { name: "username", // 用户名 type: TableStore.PrimaryKeyType.STRING, }, ], definedColumn: [ { name: "password", // 密码 type: TableStore.DefinedColumnType.DCT_STRING, }, ], }, // 为数据表配置预留读吞吐量或预留写吞吐量。0 表示不预留吞吐量,完全按量付费 reservedThroughput: { capacityUnit: { read: 0, write: 0, }, }, tableOptions: { // 数据的过期时间,单位为秒,-1 表示永不过期 timeToLive: -1, // 保存的最大版本数,1 表示每列上最多保存一个版本即保存最新的版本 maxVersions: 1, }, }; await client.createTable(table); } /** * 创建文章表 */ async function createArticleTable() { const table = { tableMeta: { tableName: "article", primaryKey: [ { name: "article_id", // 文章 ID,唯一字符串 type: TableStore.PrimaryKeyType.STRING, }, ], definedColumn: [ { name: "title", type: TableStore.DefinedColumnType.DCT_STRING, }, { name: "username", type: TableStore.DefinedColumnType.DCT_STRING, }, { name: "content", type: TableStore.DefinedColumnType.DCT_STRING, }, { name: "create_date", type: TableStore.DefinedColumnType.DCT_STRING, }, { name: "update_date", type: TableStore.DefinedColumnType.DCT_STRING, }, ], }, // 为数据表配置预留读吞吐量或预留写吞吐量。0 表示不预留吞吐量,完全按量付费 reservedThroughput: { capacityUnit: { read: 0, write: 0, }, }, tableOptions: { // 数据的过期时间,单位为秒,-1 表示永不过期 timeToLive: -1, // 保存的最大版本数,1 表示每列上最多保存一个版本即保存最新的版本 maxVersions: 1, }, }; await client.createTable(table); } (async function () { await createUserTable(); await createArticleTable(); })();
这段代码主要创建了 user 和 article 两张表,其中 user 表的主键是 username,article 表的主键是 article_id,主键的作用是方便查询。除了主键,我还定义了几个列。其实对于表格存储,默认也可以不创建列,表格存储是宽表,除主键外,数据列可以随意扩展
在完成了数据库表的创建后,我们就可以开始进行系统实现了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论