作者 | 寒斜(阿里云云原生中间件前端负责人)​

如何使用 Serverless 架构实现全双工通信的应用,Serverless 架构中数据库是如何使用的,本篇文章将为您揭开答案。

Serverless 的理念是即时弹性,用完即走。服务并非长时间运行,这也就意味着像 websocket 这种长链接的请求模式看起来并不适合 Serverless。

是否有其它的办法即可以满足长连接模式请求,又能够利用 Serverless 本身特性呢?

答案是肯定的,上一篇文章我们谈及了网关的关键作用,所以这次也是通过网关来解决全双工通信的问题。本次将以弹幕场景为例,为大家展开我们是怎么使用 Serverless 架构来实现这个场景的。



应用效果预览

弹幕应用的实用场景比较多,比如运营推广,年会活动等。但是通常实现一套带管控的流程,且部署发布的话,一般会花费比较长的时间。本篇实战则可以让你在 2 分钟之内就部署好自己的弹幕应用。同时做到支持炫彩和弹幕内容管控,你可以用它来丰富公司年会的形式。文末也会贴上源码,可以供大家参考和二次定制。



架构一览

整体架构依然采用 dns 解析 -> 网关 -> oss | fc 。不一样的是分了 3 个静态资源的工程,函数部分则采用事件驱动和 http 相结合,并且 api 部分采用 tablestore 进行数据的持久化。



流程说明

弹幕应用总工由大屏幕, 个人用户,管理员三个客户端,以及一个注册设备的服务 & api 服务组成。客户端跟服务端的长链接由网关来承载,每次客户端连接到网关的时候,网关都会存储设备编号,并且触发一次注册函数,设备编号存储到 tablestore。

当用户发起弹幕的时候经网关到 api 服务,api 服务会做一次查询先判断弹幕是否被管制,如果无管制则直接查找当前的大屏幕设备 id,并且进行网关的下行调用,网关在发到前端页面,显示数据。如果被管制,则查询在线的管理员设备,将弹幕下行通知到网关,网关发送给管理员前端页面。

数据表设计

  • 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、准备工作

同前篇《人人都是 Serverless 架构师 | 现代化 Web 应用开发实战》文章一样需要提前准备好域名,并安装好 Serverless Devs 开发者工具,以及下面的产品:

  • 云解析 DNS
  • API 网关
  • 函数计算
  • 对象存储 OSS
  • Tablestore

这次我们引入了 tablestore 的数据库记性数据的持久化功能,同样需要创建好数据库实例备用。

2、操作步骤

为了更好的展示效果,本次演示使用 ServerlessDesktop 来给大家演示一下如何 2 分钟部署一个复杂的弹幕应用。你可以根据自身需要选择 Serverless Devs Cli 或者 Serverless Desktop 对弹幕应用进行初始化和部署构建。

1)秘钥配置

可参考密钥获取文档:

http://www.serverless-devs.com/zh-cn/docs/provider-config/alibabacloud.html

2)初始化

本次初始化除了需要将应用模板下载到本地之外,还会帮忙初始化 tablestore 的表和数据,因此需要预配置几个参数:​

  • 秘钥别名 - 对应你的阿里云账号
  • 域名 - 自定义域名
  • bucketName - oss 的 bucket 名称
  • endpoint - 对应 tablestore 实例的公网访问地址
  • instance - 对应 tablestore 的实例名

预配置参数写好后点击 “确定”,接下来的工作就叫给 Serverless Devs,它会帮我们初始化弹幕应用的表。

3)构建部署

初始化之后,我们重新进入配置页面,对项目进行部署。配置信息 -> 全量操作 -> deploy 点击后其他的就交给 Serverless Devs了,它会帮助我们完成:

  1. 大屏幕,管理后台和玩家的前端部署;
  2. 注册函数以及 api 函数的部署
  3. 以及网关的路由设置和网关的域名绑定

4) 部署效果查看

  • 网关

  • 函数计算

  • Oss

  • DNS

此时访问_ barragego.serverless-developer.com _发现访问不同,检查发现原因是 apigateway 的域名和 oss 域名都未绑定成功,我们手动处理一下:





接下来再访问 barragego.serverless-developer.com 即可看到效果:

2、数据库明细

数据库方面想拿出来说一下,主要本次用的数据库确实比较新,也就是 tablestore。

1)数据库配置传递

可以看到,我们在初始化应用的时候是填写了数据库的公网访问地址和实例名称信息的,初始化的时候会把用户的输入配置写入到 s.yaml 中,这里如果是比较敏感的信息建议从 s.yaml 提取出来放到 .env 环境中,并且 ignore 掉这个文件,减少数据库信息被泄露到代码仓库的风险。

最终 Devs 会把这两个基本信息放到函数计算的环境变量中然后各运行时可以通过环境变量取到这些值,比如这里是 nodejs 的运行环境,则通过 process.env.instance 获取。

除了实例名称和公网访问地址外数据库的初始化还需要 用户的秘钥信息。鉴于秘钥信息的敏感性比较高,不建议直接把秘钥信息配置到 s.yaml 里,而是通过给函数服务授权 tablestore 角色权限,让函数内置临时秘钥信息。

  • 函数服务授权配置如下:

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

2)数据库初始化

为了减少数据库初始化次数,我们可以在函数的 initializer 方法中初始化,当函数未被释放的时候可以直接使用数据库的实例而不必重新连接。这样可以降低请求响应时间。单实例多并发的情况下比较实用。

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

tablestore 原生的 api 去做 CRUD 操作用户体验不够友好,tablestore 社区提供了一个很好的封装 SAT。我们用它来做基础的增删改查会非常的方便,代码看起来也非常整洁。


// 单主键查询
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 如何使用 websocket 的一个展示示例。你可以把它变成任意相近形态的应用,比如聊天室,多人协作平台等。

应用本身也还有很多改进空间,比如增加点赞效果,管控部分可以加上管理员的登录注册等。总之你可以根据自身需求定制更高级的功能,相关的源码已经提供出来供大家参考。下个篇章我会继续跟大家聊一聊 Serverless 和低代码的场景,并分享一个我们最近做的实践。

文中涉及网址汇总:

Serverless Devs:https://github.com/Serverless-Devs

云解析DNS:https://wanwang.aliyun.com/domain/dns

API网关:https://www.aliyun.com/product/apigateway

函数计算:https://www.aliyun.com/product/fc

对象存储OSS:https://www.aliyun.com/product/oss

ServerlessDesktop:http://www.serverless-devs.com/zh-cn/desktop/index.html

Serverless Devs Cli:http://www.serverless-devs.com/zh-cn/cli/index.html

Serverless Hub:https://serverlesshub.resume.net.cn/#/hubs/specialview

Tablestore表格存储: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

更多内容关注 Serverless 微信公众号(ID:serverlessdevs),汇集 Serverless 技术最全内容,定期举办 Serverless 活动、直播,用户最佳实践。

人人都是 Serverless 架构师 | 弹幕应用开发实战的更多相关文章

  1. 诚聘.NET架构师、高级开发工程师(2019年8月29日发布)

    招聘单位是ABP架构设计交流群(134710707)群主阳铭所在的公司 公司简介 七二四科技有限公司成立于2015年,成立之初便由金茂资本按估值2亿投资2200万,进行“健康724”平台搭建,2017 ...

  2. 葡萄城首席架构师:前端开发与Web表格控件技术解读

    讲师:Issam Elbaytam,葡萄城集团全球首席架构师(Chief Software Architect of GrapeCity Global).曾任 Data Dynamics.Inc 创始 ...

  3. 空中网招聘Java架构师、数据库开发等各类人才

    爱好网络游戏吗?爱好网站开发技术吗? 有没有想过可以成为史诗级MMO RPG<激战2>运营团队中的一员? 如果下面的职位有合适你的,加入我们吧! http://gw2.kongzhong. ...

  4. 阿里云云开发平台助力风变科技Serverless架构升级实战

    阿里云云开发平台助力风变科技Serverless架构升级实战 背景 风变科技 一个希望通过技术去推动下一代基础教育的组织.旗下产品包括第一代的熊猫书院(读书类产品).第二代的熊猫小课(泛学科综合学习平 ...

  5. 2010“架构师接龙”问答--杨卫华VS赵劼(转)

    add by zhj:虽然是几年前的文章,但还是很有参考价值的 原文:http://blog.zhaojie.me/2010/05/programmer-magazine-2010-5-archite ...

  6. 程序员、架构师、技术总监、CTO

    程序员 程序员,英文名coder/programmer,大家常自嘲叫码农的阶段.这个角色职责是把需求或产品实现为用户可用的软件产品. 此职位为执行级别.另外因为经验较少,一般需要求助别人,或与别人一起 ...

  7. IT架构师介绍-软件架构设计学习第一天(非原创)

    文章大纲 一.架构师定义二.架构师分类与具备能力三.研发人员发展的技术路线四.架构师知识体系五.参考文章   一.架构师定义   什么是架构师,这个聊架构话题时永恒的问题.每个公司对架构师的定位也有所 ...

  8. 好好讲一讲,到底什么是Java高级架构师!

    一. 什么是架构师 曾经有这么个段子: 甲:我已经应聘到一家中型软件公司了,今天上班的时候,全公司的人都来欢迎我. 乙:羡慕ing,都什么人来了? 甲:CEO.COO.CTO.All of 程序员,还 ...

  9. 如何从普通程序员晋升为架构师 面向过程编程OP和面向编程OO

    引言 计算机科学是一门应用科学,它的知识体系是典型的倒三角结构,所用的基础知识并不多,只是随着应用领域和方向的不同,产生了很多的分支,所以说编程并不是一件很困难的事情,一个高中生经过特定的训练就可以做 ...

  10. 架构之:serverless架构

    目录 简介 什么是serverless serverless的例子 简单的三层服务 消息驱动 FaaS FaaS的缺点 FaaS的优点 总结 简介 不知道什么时候,出现了一个叫做Serverless架 ...

随机推荐

  1. DES加密技术概述与应用

    一.引言 随着信息技术的飞速发展,数据安全已成为越来越受到重视的问题.数据加密技术作为保障信息安全的核心技术之一,得到了广泛的研究和应用.DES(Data Encryption Standard)作为 ...

  2. java中的try-with-resource语法

    java的世界千奇百怪...当我甩出如下代码段,不知阁下如何应对? try(A a=new A()){ 和a变量无关的业务代码块 } 没错,这就是"臭名昭著"的try-with-r ...

  3. Kylin Linux Advanced Server V10 上安装 Nacos详细步骤

    要在 Kylin Linux Advanced Server V10 上安装 Nacos,可以按照以下进行操作:1.安装 Java JDK:首先确保已在 Kylin Linux Advanced Se ...

  4. [ABC272G] Yet Another mod M

    Problem Statement You are given a sequence $A=(A_1,A_2,\dots,A_N)$ of length $N$ consisting of posit ...

  5. Nginx的安装与运行

    前言:本文是基于虚拟机上的centOS 7对Nginx的安装,可以使用uname -a查看centOS系统版本,本文用来记录安装nginx的步骤和相关命令,方便日后使用时查看. 去官网https:// ...

  6. 文心一言 VS 讯飞星火 VS chatgpt (160)-- 算法导论12.4 2题

    二.用go语言,请描述这样一棵有 n 个结点的二叉搜索树,其树中结点的平均深度为 O(lgn),但这棵树的高度是w(lgn).一棵有 n个结点的二叉搜索树中结点的平均深度为 O(lgn),给出这棵树高 ...

  7. 国家专用加密数据传输之rsa,3des加密方法-rasor3desc

    title: 国家专用加密数据传输之rsa,3des加密方法 date: 2021-12-20 13:08:21.646 updated: 2022-03-10 16:00:58.65 url: ht ...

  8. 从零玩转Websocket实时通讯服务之前后端分离版本-websocket

    title: 从零玩转Websocket实时通讯服务之前后端分离版本 date: 2021-10-25 00:47:12.945 updated: 2021-12-26 17:43:10.496 ur ...

  9. JAVAAPI实现血缘关系Rest推送到DataHub V0.12.1版本

    DataHub 更青睐于PythonAPI对血缘与元数据操作 虽然开源源码都有Java示例和Python示例:但是这个API示例数量简直是1:100的差距!!不知为何,项目使用Java编写,示例推送偏 ...

  10. 5s!用浏览器打造一个开箱即用的Linux系统

    做为Linux系统管理员.或者是系统运维工程师,肯定会在工作遇到这样的需求:需要开发环境.测试环境.准生产环境等等环境,有时候建一个环境费时间不说,还容易出各种错误,好不容易建好了,可能还用不了几天. ...