鱼耳聊天室打赏介绍与技术演进

avatar
@比心

一、什么是打赏

打赏本身不是一个新鲜的概念,从过去在路边打赏给街头艺人、歌舞厅打赏给歌手、吃饭打赏给服务员的线下打赏一直发展到现在的网络打赏,打赏的本质没有变化,只是网络打赏有了更富的打赏形式和打赏体验。  

回到我们的聊天室打赏,在传统打赏概念的基础上又提供了非常丰富的玩法和体验,整个打赏流程中大致上可以分为 4 个角色,实体和行为关系如下图:
老板:寻求娱乐消遣、情感治愈等
从业人员:陪唱歌、聊天、玩游戏等
公会:管理从业人员的档期、内容、培训、结算等 平台:给老板提供在线平台,给公会引流、提供管理后台\ 客服群

二、聊天室打赏的业务玩法

为了更好进一步理解业务,本节我们先对基本模型和玩法进行简单的介绍

2.1 聊天室模型和礼物模型的关系

在前面的系列文章已经介绍到了房间的基本模型,在我们的房间模型中礼物面板有一个向下继承的关系,所以聊天室内的礼物面板展示优先级是:房间>房间模式>房间模板,如果当前层级找不到关联的礼物面板则向上继续找,房间模型的每一层级都是可以关联礼物面板的,而最上层房间模板是必须关联礼物面板的 客服群

2.2 礼物打赏玩法

玩法涉及到的概念较多,这里挑选几个几个重要的概念解释
普通连击:礼物打赏后的 5 秒内,继续对相同收益人打赏相同礼物可以触发连击效果(信息流合并,条幅次数累加)
超级连击:将礼物按着不动,会快速的连续的进行打赏并触发普通连击
批量选项:可选择一次打赏的礼物数量
全麦打赏:自动勾选麦上所有人进行打赏
批量打赏:自己勾选麦上部分人进行打赏\ 客服群

三、聊天室打赏的技术演进

随着业务形态和业务规模的发展,技术实现也需要跟着不断的迭代和升级, 鱼耳的聊天室打赏也不例外,后面我们将重点介绍打赏初期版本存在的问题和系统重构后进行了哪些方面的升级

3.1 打赏系统 1.0

3.1.1 打赏简易流程

看起来就是一个普通的接口而已,但其实这个接口内部的逻辑已经非常的复杂了,再结合打赏的业务特性和业务的快速迭代,这样简单实现到底有哪些问题呢?\ 客服群

3.1.2 存在的问题

  • 扩展性不足 - 代码顺序编写,子逻辑耦合,方法参数太多,导致代码改动非常困难.
  • 可用性不足 - 核心打赏业务和聊天室其他业务服务共用,DB 资源共用(Mysql、Redis),打赏业务容易被其他非核心业务拖垮 + 健壮性不足 - 支付补偿逻辑不完善 - 打赏消息丢失 - 子逻辑没有解耦,支付成功后,执行后续业务逻辑,某一步报错后续业务代码都不会执行
  • 可观测性不足 - 没有业务指标大盘 - 没有业务告警

3.2 打赏系统 2.0

随着公司的发展,对聊天室打赏的稳定性、准确性和扩展性都有了更高的要求,当前的技术实现已经很难支撑业务的快速发展,于是在 2021 年的年初开始计划对打赏业务进行梳理和重构。   结合打赏的业务特性和目前存在的问题,我们主要进行了以下几个方面的改造:

3.2.1、资源隔离

为提高打赏业务的可用性,避免因聊天室其他非核心业务影响,首先进行的就是资源隔离,我们将服务层单独抽出来一个打赏服务,同时也将 Mysql 和 Redis 进行了抽取隔离。 拆分之后如下图所示: 客服群

3.2.2、代码重构

为了提高打赏业务代码的扩展性和并减少业务迭代带来技术负债,我们重新定义的打赏业务的编程范式,并按照新的编程范式进行了代码的重构。   重构后代码结构分为纵向逻辑横向逻辑。纵向逻辑为稳定代码部分,用于描述打赏的抽象过程;横向逻辑为具体业务实现,并拆分为子模块,根据业务的发展和需要可进行子模块的添加、修改、删除。打赏流程中产出的数据通过打赏上下文进行传递。其中支付后处理为异步执行部分,内部各模块独立并行执行,代码的异常不会相互之间影响。 重构后的代码内部结构图如下: 客服群

3.2.3、支付补偿

我们重新设计了支付记录表用于实现更加完善的支付补偿逻辑,整个补偿的核心在于表中定义的两个状态字段:支付状态、业务完成状态,其中支付状态比较常见不做过多解释,主要设计在于业务完成状态,业务完成状态用 bitmap 表示,每一位表示一个具体业务的完成结果,如下图所示:

客服群

支付的流程有几个关键点先提一下

  1. 业务处理类需要支持幂等性,用于满足业务超时场景进行重复调用执行
  2. 未知的支付错误码都要和支付调用超时一样处理,除非是已明确的支付失败
  3. 业务处理类每执行成功一个,则更新 bitmap 上对应下标的值为 1

支付流程图(附带后续业务处理)如下图所示:\ 客服群

支付状态补偿用于处理支付超时的数据,流程图如下:\ 客服群

业务状态补偿用于处理业务执行失败的数据,补偿流程图如下: 客服群

3.2.4、消息准确性

聊天室互动性较强,有非常多的玩法通过房间 IM 驱动,房间 IM 之前使用的云商服务,受制于云商对于单房间每秒消息条数的限制,导致许多重要的消息(例如打赏特效)被丢弃。同时没有消息必达机制和完备的监控(云商侧属于黑盒,出了问题只能等他们的技术人员排查),导致用户体验非常的不好。基于以上这些痛点我们主要做了有如下优化:

1、云商逐渐切换为自建长链

在之前公司的技术储备中已经通过了足够长的时间验证来证明自建长链的性能、稳定性以及使用成本都优于云商。同时使用自建长链可以有更多的定制化需求,同时可以闭环消息链路。

2、消息分级&流控

我们将现有的所有消息进行了分类,将消息分为了 4 个等级(高、中高、中、低),以达到业务需求和消息容量的平衡。同时使用 redis+lua 脚本实现了不同等级的流控。通过这样的改造之后相当于把高等级消息的整个通道资源隔离了,从而极大提高了高价值礼物特效的送达率。 客服群

3、消息必达

在长链协议头中添加了 ack 标识,并通过业务侧回复 ack 消息和定时重发消息实现,简易流程图如下: 客服群

3.2.5、监控告警

打赏大盘指标

  • 最近 30 天,每天的总打赏笔数&金额
  • 最近 30 天,每天 top20 用户打赏笔数&笔数
  • 当天,top20 房间打赏金额&笔数
  • 当天,支付处理中的数据
  • 当天,自动补偿处理的数据
  • 支付结果分布

打赏监控告警指标

  • 最近 3 分钟,端到端网络成功率低于 98% 告警到钉钉群
  • 最近 3 分钟,打赏业务成功率高于低于 90% 告警到钉钉群
  • 最近 10 分钟打上请求数上升或下降超过 100%,告警到钉钉群
  • 最近 5 分钟,打赏请求数跌 0,告警到钉钉群

消息链路串联

从用户发起打赏一直到客户端展示打赏特效,中间的流程非常长且有许多的异步流程,导致排查问题非常的困难且耗时,因此我们在入口端生成了 traceId,并且打通了中间所有链路,最终到客户端打赏也会带上 traceId,链路如下图所示: 客服群

四、sona 开源推广

我们在去年 12 月份开源了 sona(sona 是一个支持快速搭建语音房产品的全端解决方案,支撑了比心聊天室、直播、游戏房等业务),需要大家帮忙在朋友圈宣传一下,github 上求个 star,谢谢大家!∠(° ゝ °) github.com/BixinTech/s…

客服群

wxg.JPG