ToC业务用户弹窗的技术方案

2023-04-01 11:19:31 浏览数 (1)

现在很多 ToC 客户端,比如:滴滴、美团、携程等等,都有很多的弹窗,那后端怎么设计更合理、更方便、成本更低呢?

我这里说的弹窗是说一级页面的弹窗,比如客户端的首页、个人中心页面、订单页面等。这种一级页面一般都有专门的部门负责,其他业务方需要接入弹窗,需要通过这个部门来接入。这里定义两种角色:

  • 接入方,是需要在首页等页面投放弹窗的业务部门。
  • 公共,负责首页等公共页面的部门。

这里是我们的设计方案:

1 弹窗后端接口设计

1.1 弹窗类型很重要

首先要约束弹窗类型,

| 序号 | 弹窗类型 | 类型说明 | | :- | :- | :- | | 1 | 单图片 | 弹出一张图片,点击图片跳转 | | 2 | 单Lottie | 弹出一个动图,点击动图或者按钮跳转 | | 3 | 双Lottie | 弹出一个动图,点击或者自动跳转第二个动图,点击第二个动图跳转| | 4 | 其他弹窗1 | 比如,需要前端拼接展示完整图片的类型 | | 5 | 其他弹窗 | 需要不同组合字段组合弹窗资源的都算一种类型 |

1.2 弹窗接口设计

字段名称

二级字段

字段类型

说明

status

int

成功失败状态码

message

String

成功失败信息

data

popName

String

弹窗名称,可以用来埋点和弹窗区分

popInfo

Object

弹窗资源资源,每个类型弹窗里面字段不一致

比如图片弹窗 popInfo

字段名称

字段类型

说明

imgaeUrl

String

图片url

imageWidth

int

图片宽度

imageHeight

图片高度

jumpUrl

String

跳转url

popType

int

弹窗类型

其他类型弹窗按需设计字段即可

2 配置即弹窗

标准类型的弹窗要支持配置即可,不用重复开发,要支持配置,可以有两种类型:

  • 是所有人都出的弹窗,直接配置静态资源即可。
  • 种是根据各个接入方自己的条件判断是否出,弹窗资源接入方自己控制,这种需要接入方提供一个接口,这个接口是一个标准接口。

第一种方式比较简单,就不说了。直接说第二种,直接制定一个标准接口,接入方直接实现即可。

统一入参,仅供参考,按需设计即可:

字段名称

字段类型

说明

userId

String

用户id

userName

String

用户昵称

deviceId

String

设备id

lat

String

纬度

lon

String

经度

统一出参,这里以单图片弹窗为例:

字段名称

二级字段

字段类型

说明

status

int

成功失败状态码

message

String

成功失败信息

data

imgaeUrl

String

图片url

imageWidth

int

图片宽度

imageHeight

int

图片高度

jumpUrl

String

跳转地址

其他通用字段

String

埋点等通用字段

接入的时候,公共方配置接入方的接口地址即可。

3 频控的两种技术方案

基本上除了某些 APP 之外,所有 APP 的弹窗都不会无限制的弹,都需要频控,否则可能导致用户体验的下降和用户的流失。

3.1 redis setex 弹出缓存自动过期

用户每次弹窗都使用redis 的 setex 设置过期时间,这个时间就是业务允许两次弹窗之间的最小间隔时间。

key 设计:popName userId

优点:

  1. 所有弹窗频控后端可控。
  2. 有问题,可操作性强,可以操作redis,去除某些用户的频控限制。

缺点:

  1. 需要redis,造成架构复杂度上升,如果其他功能不需要使用 redis 的情况下,造成成本上涨。
  2. 用户量大的情况,比如上亿:redis 的key会非常大,造成redis压力。

3.2 前端缓存每个弹窗的最近一次弹出时间

前端存储每个用户弹窗的时间,请求后端的时候,把所有弹窗的上次弹出时间带给后端,由后端计算是否在频控时间范围内。

新弹窗弹出时间,由后端返给前端,前端存储,下次请求的时候带给后端。

优点:

  1. 不需要额外的存储,弹窗上次弹出时间存储在用户的客户端中。
  2. 架构简单。
  3. 问题好排查,直接看请求参数即可。

缺点:

  1. 用户卸载重装客户端的时候,会导致数据丢失,造成频控失效;
  2. 整个频控需要前后端配合才能完成,任何一方有问题,都有可能导致功能出问题。

4 怎么保证速度

异步执行所有弹窗,按顺序返回第一个有数据的弹窗, 参考:Reactor 之 多任务并发执行,结果按顺序返回第一个

欢迎大家提供更好的实现

0 人点赞