人人都是 Serverless 架构师 | 弹幕应用开发实战

作者 | 寒斜(阿里云云原生中间件前端负责人)
如何使用 Serverless 架构实现全双工通信的应用,Serverless 架构中数据库是如何使用的,本篇文章将为您揭开答案。

应用效果预览

架构一览

流程说明
数据表设计
- equipment(设备) 
| 字段 | 类型 | 说明 | 
| id | string | 设备表主键 | 
| deviceld | string | 设备id | 
| docld | string | 备用字段 | 
| type | string | 设备类型(screen | admin) | 
- barrage(弹幕) 
| 字段 | 类型 | 说明 | 
| gid | string | 分区键 | 
| id | integer | 主键自增 | 
| fromId | string | 弹幕作者id | 
| fromName | string | 来源作者名称 | 
| color | string | 弹幕颜色 | 
| fontSize | string | 弹幕字体大小 | 
| checkStatus | integer | 弹幕状态0(未处理)1(审批通过)2(审批未过) | 
| sendTime | string | 弹幕发送时间 | 
| checkTime | string | 弹幕更新时间 | 
| message | string | 弹幕内容 | 
- interceptor (过滤器) 
| 字段 | 类型 | 说明 | 
| id | integer | 主键/分区键 | 
| status | integer | 拦截状态0不拦截 1拦截 2拦截加过滤 | 
| filterWords | string | 过滤字段 | 
1、准备工作
- 云解析 DNS 
- API 网关 
- 函数计算 
- 对象存储 OSS 
- Tablestore 
2、操作步骤
1)秘钥配置
2)初始化
本次初始化除了需要将应用模板下载到本地之外,还会帮忙初始化 tablestore 的表和数据,因此需要预配置几个参数:
- 秘钥别名 - 对应你的阿里云账号 
- 域名 - 自定义域名 
- bucketName - oss 的 bucket 名称 
- endpoint - 对应 tablestore 实例的公网访问地址 
- instance - 对应 tablestore 的实例名 
3)构建部署
- 大屏幕,管理后台和玩家的前端部署; 
- 注册函数以及 api 函数的部署 
- 以及网关的路由设置和网关的域名绑定 

4) 部署效果查看
- 网关 


- 函数计算 

- Oss 

- DNS 





2、数据库明细
1)数据库配置传递
- 函数服务授权配置如下: 

- 函数内获取秘钥信息如下: 

2)数据库初始化
exports.initializer = (context, callback) => {try {const ak = context.credentials.accessKeyId;const sk = context.credentials.accessKeySecret;const stsToken = context.credentials.securityToken;SAT.init(endpoint, instance, ak, sk, stsToken);internal = { tableClient: SAT, TableStore };callback();} catch (err) {callback(err.message);}}
3)CRUD
// 单主键查询const getInterceptor = async (ctx) => {const { tableClient } = ctx.req.requestContext.internal;const res = await tableClient.table('interceptor').get(1, cols = []);return res;}// 查询全部const getAllEquipment = async (tableClient,TableStore) => {const res = await tableClient.table('equipment').getRange(TableStore.INF_MIN, TableStore.INF_MAX, cols = [])return Object.keys(res).map((key)=> res[key]);}// 双主键(一个分区键,一个自增键)的插入const addBarrage = async (ctx) => {const { tableClient, TableStore } = ctx.req.requestContext.internal;const { fromId, fromName, color, fontSize = '28px', checkStatus = 0, message } = ctx.request.body;const currentTime = Date.now().toString();const newData = Object.assign({}, { fromId, fromName, color, fontSize, checkStatus: parseInt(checkStatus), message }, { sendTime: currentTime, checkTime: currentTime });const res = await tableClient.table('barrage', ['gid', 'id']).put([1, TableStore.PK_AUTO_INCR], newData, c = 'I');return res;}// 更新const updateBarrage = async (ctx) => {const { tableClient } = ctx.req.requestContext.internal;const { checkStatus } = ctx.request.body;const { id } = ctx.request.params;const currentTime = Date.now().toString();const res = await tableClient.table('barrage', ['gid', 'id']).update([1, parseInt(id)], { checkStatus: parseInt(checkStatus), checkTime: currentTime }, c = 'I')return res;}// 条件查询const getBarrageByCondition = async (ctx) => {const { tableClient, TableStore } = ctx.req.requestContext.internal;const res = await tableClient.table('barrage').search('index', ['checkStatus', 0])return res;}
当然如果你想做更高级的查询,就需要自己去查阅官网文档了。 
总结
文中涉及网址汇总:
Serverless Devs:https://github.com/Serverless-Devs云解析DNS:https://wanwang.aliyun.com/domain/dnsAPI网关:https://www.aliyun.com/product/apigateway函数计算:https://www.aliyun.com/product/fc对象存储OSS:https://www.aliyun.com/product/ossServerlessDesktop:http://www.serverless-devs.com/zh-cn/desktop/index.htmlServerless Devs Cli:http://www.serverless-devs.com/zh-cn/cli/index.htmlServerless Hub:https://serverlesshub.resume.net.cn/#/hubs/specialviewTablestore表格存储:https://www.aliyun.com/product/ots官网文档:https://help.aliyun.com/document_detail/27304.html?spm=5176.54465.J_7985555940.4.15942e0c3qkHbU源码:https://github.com/devsapp/start-barrage
作者介绍:
 
 
 奖励看到最后的你:
  奖励看到最后的你:
# 点个在看,并在下方留言;
# 然后,将后台回复云小宝,试试手气?
# 本周互动奖品是“云小宝公仔”
# 本期礼品开奖时间1月12日

订阅话题 精彩资讯不错过

 戳原文,跳转至 Serverless Devs~
 戳原文,跳转至 Serverless Devs~评论
