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

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

serverless的理念是即时弹性,用完及走。服务并非长时间运行,这也就意味着像websocket这种长链接的请求模式看起来并不适合serverless,但是否有其他的办法即能满足长连接模式请求,也能够利用serverless本身特性呢?答案是肯定的,从前面的一篇文章我们看到了网关的关键作用,所以这次也是通过网关来解决全双工通信的问题。本次以弹幕场景为例来为大家展开我们是怎么使用serverless架构来实现这个场景的。

应用效果预览

image.png

弹幕应用的实用场景比较多,比如运营推广,年会活动等。本次弹幕应用演示的源码均已放至github,大家可以自行修改使用

架构一览

image.png

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

流程说明

image.png

弹幕应用总共由大屏幕个人用户管理员三个客户端,以及一个注册设备的服务和一个api服务。客户端跟服务端的长链接由网关来承载,每次客户端连接到网关的时候,网关都会存储设备编号,并且触发一次注册函数,设备编号存储到tablestore。当用户发起弹幕的时候经网关到api服务,api服务会做一次查询先判断弹幕是否被管制,如果无管制则直接查找当前的大屏幕设备id,并且进行网关的下行调用,网关在发到前端页面,显示数据。如果被管制,则查询在线的管理员设备,将弹幕下行通知到网关,网关发送给管理员前端页面。

数据表设计

equipment(设备)

字段

类型

说明

id

string

设备表主键

deviceId

string

设备id

docId

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

过滤字段

准备工作

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

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

操作步骤

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

秘钥配置

初始化

www5.gif

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

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

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

构建部署

初始化之后,我们重新进入配置页面,对项目进行部署。配置信息->全量操作->deploy 点击后其他的就交给Serverless Devs了,他会帮助我们完成 大屏幕,管理后台和玩家的前端部署,注册函数以及api函数的部署以及网关的路由设置和网关的域名绑定


www6.gif


部署效果查看

网关

image.png

image.png

函数计算

image.png

Oss

image.png

DNS

image.png

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

image.png

image.png

image.png

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

www7.gif


数据库明细

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

数据库配置传递

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

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

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

函数服务授权配置如下:

image.png

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

image.png

数据库初始化

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

exports.initializer= (context, callback) => {
try {
constak=context.credentials.accessKeyId;
constsk=context.credentials.accessKeySecret;
conststsToken=context.credentials.securityToken;
SAT.init(endpoint, instance, ak, sk, stsToken);
internal= { tableClient: SAT, TableStore };
callback();
  } catch (err) {
callback(err.message);
  }
}

数据库实例初始化之后,我们通过赋值给全局变量来从其他的方法中取得实例,进行后续的操作

CRUD

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

// 单主键查询constgetInterceptor=async (ctx) => {
const { tableClient } =ctx.req.requestContext.internal;
constres=awaittableClient.table('interceptor').get(1, cols= []);
returnres;
}
// 查询全部constgetAllEquipment=async (tableClient,TableStore) => {
constres=awaittableClient.table('equipment').getRange(TableStore.INF_MIN, TableStore.INF_MAX, cols= [])
returnObject.keys(res).map((key)=>res[key]);
}
// 双主键(一个分区键,一个自增键)的插入constaddBarrage=async (ctx) => {
const { tableClient, TableStore } =ctx.req.requestContext.internal;
const { fromId, fromName, color, fontSize='28px', checkStatus=0, message } =ctx.request.body;
constcurrentTime=Date.now().toString();
constnewData=Object.assign({}, { fromId, fromName, color, fontSize, checkStatus: parseInt(checkStatus), message }, { sendTime: currentTime, checkTime: currentTime });
constres=awaittableClient.table('barrage', ['gid', 'id']).put([1, TableStore.PK_AUTO_INCR], newData, c='I');
returnres;
}
// 更新constupdateBarrage=async (ctx) => {
const { tableClient } =ctx.req.requestContext.internal;
const { checkStatus } =ctx.request.body;
const { id } =ctx.request.params;
constcurrentTime=Date.now().toString();
constres=awaittableClient.table('barrage', ['gid', 'id']).update([1, parseInt(id)], { checkStatus: parseInt(checkStatus), checkTime: currentTime }, c='I')
returnres;
}
// 条件查询constgetBarrageByCondition=async (ctx) => {
const { tableClient, TableStore } =ctx.req.requestContext.internal;
constres=awaittableClient.table('barrage').search('index', ['checkStatus', 0])
returnres;
}

当然如果你想做更高级的查询,就需要自己去查阅官网文档

更多

这个项目本身是对serverless 如何使用websocket的一个展示示例,你可以把他变成任意相近形态的应用,比如聊天室,多人协作平台等。应用本身可以拿过去做二次改进,比如增加点赞,管控部分可以加上管理员的登录注册等。总之你可以根据自身需求定制更高级的功能,相关的源码已经提供出来供大家参考,下个篇章会跟大家聊一聊serverless和低代码的场景,分享一个我们最近做的实践。


相关实践学习
函数计算部署PuLID for FLUX人像写真实现智能换颜效果
只需一张图片,生成程序员专属写真!本次实验在函数计算中内置PuLID for FLUX,您可以通过函数计算+Serverless应用中心一键部署Flux模型,快速体验超写实图像生成的魅力。
从 0 入门函数计算
在函数计算的架构中,开发者只需要编写业务代码,并监控业务运行情况就可以了。这将开发者从繁重的运维工作中解放出来,将精力投入到更有意义的开发任务上。
目录
相关文章
|
12月前
|
存储 运维 Serverless
千万级数据秒级响应!碧桂园基于 EMR Serverless StarRocks 升级存算分离架构实践
碧桂园服务通过引入 EMR Serverless StarRocks 存算分离架构,解决了海量数据处理中的资源利用率低、并发能力不足等问题,显著降低了硬件和运维成本。实时查询性能提升8倍,查询出错率减少30倍,集群数据 SLA 达99.99%。此次技术升级不仅优化了用户体验,还结合AI打造了“一看”和“—问”智能场景助力精准决策与风险预测。
1080 69
|
11月前
|
数据采集 运维 监控
Serverless爬虫架构揭秘:动态IP、冷启动与成本优化
随着互联网数据采集需求的增长,传统爬虫架构因固定IP易封禁、资源浪费及扩展性差等问题逐渐显现。本文提出基于Serverless与代理IP技术的新一代爬虫方案,通过动态轮换IP、弹性调度任务等特性,显著提升启动效率、降低成本并增强并发能力。架构图与代码示例详细展示了其工作原理,性能对比数据显示采集成功率从71%提升至92%。行业案例表明,该方案在电商情报与价格对比平台中效果显著,未来有望成为主流趋势。
447 0
Serverless爬虫架构揭秘:动态IP、冷启动与成本优化
|
10月前
|
人工智能 Serverless API
Serverless 加 AI 让应用开发更简单
本文介绍了 Serverless 技术在 AI 领域的应用及 FunctionAI 平台的功能与优势。首先探讨了 Serverless 解决的核心问题,包括降低成本和提升效率。接着分析了构建 AI 应用的阻碍因素,如技术积累不足、大模型迭代快及算力资源有限。FunctionAI 平台通过按需模型托管、一键部署、流程式开发工具和灵活组装能力,帮助企业降低试错成本并提高开发效率。平台架构分为四层,涵盖模型层、开发层、服务层和部署层。实际应用场景包括图像生成、外部开发者支持及大流量处理等。最后,通过客户案例展示了平台在弹性扩展与成本优化方面的价值。
|
12月前
|
Cloud Native Serverless 流计算
云原生时代的应用架构演进:从微服务到 Serverless 的阿里云实践
云原生技术正重塑企业数字化转型路径。阿里云作为亚太领先云服务商,提供完整云原生产品矩阵:容器服务ACK优化启动速度与镜像分发效率;MSE微服务引擎保障高可用性;ASM服务网格降低资源消耗;函数计算FC突破冷启动瓶颈;SAE重新定义PaaS边界;PolarDB数据库实现存储计算分离;DataWorks简化数据湖构建;Flink实时计算助力风控系统。这些技术已在多行业落地,推动效率提升与商业模式创新,助力企业在数字化浪潮中占据先机。
610 12
|
人工智能 运维 Devops
CAP:Serverless + AI 让应用开发更简单
CAP:Serverless + AI 让应用开发更简单
213 9
|
人工智能 运维 架构师
Serverless + AI 让应用开发更简单,加速应用智能化
Serverless + AI 让应用开发更简单,加速应用智能化
291 5
|
Kubernetes 监控 Serverless
基于阿里云Serverless Kubernetes(ASK)的无服务器架构设计与实践
无服务器架构(Serverless Architecture)在云原生技术中备受关注,开发者只需专注于业务逻辑,无需管理服务器。阿里云Serverless Kubernetes(ASK)是基于Kubernetes的托管服务,提供极致弹性和按需付费能力。本文深入探讨如何使用ASK设计和实现无服务器架构,涵盖事件驱动、自动扩展、无状态设计、监控与日志及成本优化等方面,并通过图片处理服务案例展示具体实践,帮助构建高效可靠的无服务器应用。
|
人工智能 运维 Serverless
Serverless + AI 让应用开发更简单
Serverless + AI 让应用开发更简单
486 2
|
Cloud Native 安全 Serverless
云原生应用实战:基于阿里云Serverless的API服务开发与部署
随着云计算的发展,Serverless架构日益流行。阿里云函数计算(Function Compute)作为Serverless服务,让开发者无需管理服务器即可运行代码,按需付费,简化开发运维流程。本文从零开始,介绍如何使用阿里云函数计算开发简单的API服务,并探讨其核心优势与最佳实践。通过Python示例,演示创建、部署及优化API的过程,涵盖环境准备、代码实现、性能优化和安全管理等内容,帮助读者快速上手Serverless开发。
|
存储 消息中间件 人工智能
基于 Apache RocketMQ 的 ApsaraMQ Serverless 架构升级
基于 Apache RocketMQ 的 ApsaraMQ Serverless 架构升级
330 0

相关产品

  • 函数计算