大屏技术演进-拉模式

794 阅读7分钟

一、背景

产品经理:我们要实现如下的一个形如下图的一个大屏需求,目前我们所有的日志数据都在库里面,应该不是很难吧


图片来源与网络,如果侵权请及时联系删除

技术小哥哥:嗯,难道是不难,我要回去看看日志的数据量,然后再制定对应技术方案,然后在一起评审,接下来就是做需求分析和技术方案了。

这种技术需求应该在一些to b的公司业务是比较常见的,很荣幸自己参与系统的大屏从1.0到2.0的升级操作

二、需求分析

与前端定义格式

一期因为时间关系,就采用的是http+json定时拉取的方式获取,这个方式在很多场景下面是非常好的,因为http协议成熟与稳定,json格式比较大众,现在基本的语言都支持对应的编码操作。

后端技术方案

  1. 每次请求直接从日志表来进行数据获取。
  2. 使用脚本将日志数据生成一份基础数据,然后给前端直接调用。
  3. 用消息队列进行订阅/推送模式,增加一个新的topic供大屏业务使用,后续与第二个方案差不多,也是生成一个基础数据存储在库里面。
  4. 根据页面的条件,生成每个组合条件的数据供前端调用,这里会借助redis来进行存储,至于为什么使用redis,这里不进行介绍了,社区有很多关于redis介绍文章。

1-3其实都可以理解为一种拉模式,因为都是在请求时候进行前端数据的组合,至于2-3仅仅是将数据进行压缩减小,比如减小到分钟级别,毕竟一般日志数据都是秒级别的。

4其实是一种推模式,如果直接使用http,在后台逻辑是拉,对于前端也是拉,这种方案一般会使用websocket进行推模式的获取,这个会在 下一篇 文章进行描述

三、技术方案制定

本篇文章不会有代码实现来做,因为讲原理方案,任何后端语言都是可以拿来实现的。

1、前端请求,后端直接拉日志数据统计

    优点:

  • 简单方便,可以直接发起ajax请求就可以获取数据
  • 后端也方便,并且不需要改动太多原来的表存储方法,不需要扩展表数据
    缺点:
  • 数据量大,就会知道你是在考验数据库的承受能力了
  • 条件太多情况下,及时你设置了每个条件模块的缓存,但是大屏数据及时性比较高,缓存命中率低,所以这个方案下面缓存设置没有太多意义

    流程图:


    流程说明:

  1. 终端进行日志请求上报,请求的日志经过同意网关的认证以及基础的字段校验,校验通过后将数据写入到消息队列里面。
  2. 开启一个消费者,持续消费消息队列里面数据,将消息队列的数据异步写入到数据库里面,这里使用异步消费其实就是将大量并发的终端请求做一个控制处理,防止大量请求直接穿透到数据库,数据库资源在整个系统架构中是比较宝贵的,最好不要因为请求的激增出现宕机情况。
  3. 前端大屏发起数据请求,直接到我们的web服务器,web服务器通过反向代理方式给到我们服务端业务逻辑服务器,服务端业务逻辑服务器直接从数据库拉取数据分析聚合再返回


2、后端使用脚本生成每分钟数据,供前端接口调用

    优点:

  • 简单方便,可以直接发起ajax请求就可以获取数据
  • 会比上面的方案少很多数据,特别是在每分钟密集型日志上,因为原来一分钟估计会有1w条记录,而用异步脚本生成后就是一条了,在后续的前端请求逻辑上,做出的响应会更及时。

    缺点:

  • 需要额定扩展一张统计表,有维护额外统计表的成本
  • 这里只是减少了数据的一个条数,当业务需求需要到秒级别的时候,这个方案又是一个积累的存在了

   流程图:

流程说明(与第一个在收集过程一致,不再赘述):

  • 当日志收集入库后,我们会有定时脚本任务将日志的数据读取出来进行分析聚合存储到我们的统计表里面。
  • 前端的逻辑在请求过来后,就不会在日志库进行读取了,而是直接去了已经统计好的数据表,这个统计好区别后面文章说的按条件区分好的统计数据。


3、消息队列方式进行异步统计数据,供前端接口调用

    优点:

  • 前端层面来讲,调用还是比较方便的
  • 因为是异步进行数据统计,所以不会影响整体的前端请求的响应时间,对应cpu和内存占用暂时不在这考虑,这里主要是因为进程间已经隔离

    缺点:

  • 与第二个一样,需要增加一个统计表,对于统计表的维护问题
  • 这里也是减少了数据的个数条数的问题,对于产品来讲,时间粒度更改为每秒,整个表的统计粒度就gg了
  • 增加了消息队列组件,整个系统架构上会复杂一点,当然现在一般系统消息队列是标配了,所以这个缺点也是最不起眼的缺点了

    流程图


    流程说明:

  1. 收集与第一个方案不一样在于,我们同时会入两个队列,当然在一些支持多播的消息队列完全可以共用哈,当然如果是服务化架构的话,统计与收集应该不会同一个服务了
  2. 统计队列的消费者获取到数据后,进行统计逻辑直接入了统计表,供前端接口来调用。


四、总结

  • 我们这里都没有使用缓存来做一些防止数据穿透问题,当然在现实方案部署肯定有缓存来做,这里没做是因为对于整体方案架构来讲不必过于复杂了,当然在大屏的需求上,其实前端请求的缓存么有太大作用,我们要的基本是实时数据,而缓存基本都是历史的数据
  • 整体的三个方案,我们第一期选择的是第二个方案,第一个太过于简单粗暴了,数据库扛不住;当然第三个其实与第二个也差不多,如果需求要求比较准确点的话,比如要精确到秒,第三个也是可以的,而我们需求刚好是精确到分,这就没必要每个日志来都要进行数据统计操作
  • 世界上没有最优的方案,只有最适合需求的技术方案,当然需求不合理,还是可以好好反驳的。


五、思考

  • 我们这篇文章基本用的是拉数据方式,可以理解为,我们的前端需要的数据逻辑都是在请求同步来获取的,如果这个大屏条件比较单一,其实这个方案是没有太大问题的,毕竟简单一点,所以我们定义为1.0版本方案。
  • 那么如果我们有条件选择呢?如果我们要看: 24小时数据 、1小时数据 、30分钟数据,这是我们下一期需要讲的一个技术方案,期待我们的新技术方案