人人都是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和低代码的场景,分享一个我们最近做的实践。


相关实践学习
【玩转ComfyUI】基于函数计算一键部署AI生图平台ComfyUI
本次实验将带大家通过使用阿里云产品函数计算FC,快速使用ComfyUI实现更高质量的图像生成。
从 0 入门函数计算
在函数计算的架构中,开发者只需要编写业务代码,并监控业务运行情况就可以了。这将开发者从繁重的运维工作中解放出来,将精力投入到更有意义的开发任务上。
目录
相关文章
|
8月前
|
人工智能 运维 Kubernetes
Serverless 应用引擎 SAE:为传统应用托底,为 AI 创新加速
在容器技术持续演进与 AI 全面爆发的当下,企业既要稳健托管传统业务,又要高效落地 AI 创新,如何在复杂的基础设施与频繁的版本变化中保持敏捷、稳定与低成本,成了所有技术团队的共同挑战。阿里云 Serverless 应用引擎(SAE)正是为应对这一时代挑战而生的破局者,SAE 以“免运维、强稳定、极致降本”为核心,通过一站式的应用级托管能力,同时支撑传统应用与 AI 应用,让企业把更多精力投入到业务创新。
820 30
|
9月前
|
存储 人工智能 Serverless
函数计算进化之路:AI 应用运行时的状态剖析
AI应用正从“请求-响应”迈向“对话式智能体”,推动Serverless架构向“会话原生”演进。阿里云函数计算引领云上 AI 应用 Serverless 运行时技术创新,实现性能、隔离与成本平衡,开启Serverless AI新范式。
870 12
|
8月前
|
Cloud Native Serverless API
微服务架构实战指南:从单体应用到云原生的蜕变之路
🌟蒋星熠Jaxonic,代码为舟的星际旅人。深耕微服务架构,擅以DDD拆分服务、构建高可用通信与治理体系。分享从单体到云原生的实战经验,探索技术演进的无限可能。
微服务架构实战指南:从单体应用到云原生的蜕变之路
|
8月前
|
监控 Cloud Native Java
Spring Boot 3.x 微服务架构实战指南
🌟蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕Spring Boot 3.x与微服务架构,探索云原生、性能优化与高可用系统设计。以代码为笔,在二进制星河中谱写极客诗篇。关注我,共赴技术星辰大海!(238字)
1331 2
Spring Boot 3.x 微服务架构实战指南
|
9月前
|
消息中间件 数据采集 NoSQL
秒级行情推送系统实战:从触发、采集到入库的端到端架构
本文设计了一套秒级实时行情推送系统,涵盖触发、采集、缓冲、入库与推送五层架构,结合动态代理IP、Kafka/Redis缓冲及WebSocket推送,实现金融数据低延迟、高并发处理,适用于股票、数字货币等实时行情场景。
1429 3
秒级行情推送系统实战:从触发、采集到入库的端到端架构
|
9月前
|
设计模式 人工智能 API
AI智能体开发实战:17种核心架构模式详解与Python代码实现
本文系统解析17种智能体架构设计模式,涵盖多智能体协作、思维树、反思优化与工具调用等核心范式,结合LangChain与LangGraph实现代码工作流,并通过真实案例验证效果,助力构建高效AI系统。
986 7
|
9月前
|
人工智能 运维 安全
聚焦 AI 应用基础设施,云栖大会 Serverless AI 全回顾
2025 年 9 月 26 日,为期三天的云栖大会在杭州云栖小镇圆满闭幕。随着大模型技术的飞速发展,我们正从云原生时代迈向一个全新的 AI 原生应用时代。为了解决企业在 AI 应用落地中面临的高成本、高复杂度和高风险等核心挑战,阿里云基于函数计算 FC 发布一系列重磅服务。本文将对云栖大会期间 Serverless+AI 基础设施相关内容进行全面总结。
|
9月前
|
JSON 供应链 监控
1688商品详情API技术深度解析:从接口架构到数据融合实战
1688商品详情API(item_get接口)可通过商品ID获取标题、价格、库存、SKU等核心数据,适用于价格监控、供应链管理等场景。支持JSON格式返回,需企业认证。Python示例展示如何调用接口获取商品信息。
|
9月前
|
人工智能 Kubernetes 安全
重塑云上 AI 应用“运行时”,函数计算进化之路
回顾历史,电网的修建,深刻地改变了世界的经济地理和创新格局。今天,一个 AI 原生的云端运行时的进化,其意义也远不止于技术本身。这是一次设计哲学的升华:从“让应用适应平台”到“让平台主动理解和适应智能应用”的转变。当一个强大、易用、经济且安全的 AI 运行时成为像水电一样的基础设施时,它将极大地降低创新的门槛。一个独立的开发者、一个小型创业团队,将有能力去创造和部署世界级的 AI 应用。这才是技术平权的真谛,是激发全社会创新潜能的关键。

相关产品

  • 函数计算