返回介绍

2.1 内容管理系统的架构设计

发布于 2024-01-20 01:12:18 字数 3509 浏览 0 评论 0 收藏 0

在进行架构设计前,你要明确系统的需求。对于一个内容管理系统,最核心的功能(也是这一讲要实现的功能),主要有这样几个:

  • 用户注册;
  • 用户登录;
  • 发布文章;
  • 修改文章;
  • 删除文章;
  • 查询文章。

这 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文