前言

最近成为了 Warning Master (调侃)
因为最近接手了3个预警项目,都是要做各个类别数值统计计算指标的预警
感觉挺有趣的,就想记录下来

这三个项目分别为:

  1. 某A外企啤酒公司
  2. 某B国际航空公司
  3. 某C会员超市公司

小小的项目背景

某A外企啤酒公司项目要做预警是由于在2023年底的时候爆出来了一个生产问题,是由于当时代码分支记录混乱,最后上线的包版本缺少了部分 commit 提交,最后引发了比较惨烈的生产问题,结果是领导也没有深究(毕竟是领导在分支上管理不太好,也没有同步消息,修复的BUG在一个bugfix分支,没有在项目分支上)。

紧接着引发了客户投诉,说是出现了好几天的数据异常,导致他们判断有误,所以客户要求我们赠送一个预警系统(简易),以此来兜住这种类似的问题。项目管理说最好以最小的成本完成该内容,甚至没有前端,纯后端进行数据计算统计、触发预警等。开发周期大概5-7天,由我来主导设计架构。

在2024年初的时候,某A外企啤酒公司项目又爆了一个生产问题,本次生产事故是产品缺陷,导致报错影响了主流程判断。是由于客户项目是在好几年前买了的,是1.1.0版本,目前我们的版本已经是1.5.4+了,这个问题已经在新版本修复,但是旧版本没有修复,最终导致本次报错。客户认为该内容属于产品缺陷,我们应在修复产品缺陷时回归同步项目代码,公司侧认为只在新版本进行更新和维护,旧版本出现且新版本已修复问题应按需所求去同步。因此客户发起二期预警的需求,本次二期预警改动量较大,影响第一次的整体内容(由于第一次项目经理要求以最简单的方式开发,没有留太多拓展的口子)

某B国际航空公司项目是客户购买的看板趋势产品,要求携带预警功能,该预警功能设计架构与某A外企啤酒公司项目又不一致,且我在有一段时间既参加A有参加B的开发任务,导致思维也比较跳跃。

某C会员超市公司项目,目前主管只让我评估了对应的工作量,还没有进行开发,所以目前也没有开始设计。

方案设计

下面我会讲解两种方案设计,分别是 某A外企啤酒公司某B国际航空公司 项目现在的预警方案设计。他们其中有一些共同点,也有一些不同的底层设计,具体是由于需求所导向。

某A外企啤酒公司

  1. 每天数据量: 25w+
  2. 数据来源: Elasticsearch
  3. 需求说明: 支持天类型与小时类型的预警 (天类型:当前天开始至目前时间的数据量 与 过去七天均值进行对比,看环比上升或下降率是否满足预警要求;小时类型:当前小时段与过去七天该小时段均值进行对比,看环比上升或下降率是否满足预警要求)
  4. 额外补充: 没有前端页面展示,需要手动在某配置中写 Json,仅后端去做数据计算和触发

某A外企啤酒公司-流程图

说明

这个项目主要就是两个定时任务来运转整体预警系统的,定时任务分别去做存储和触发两个事情。我们的数据来源基本上是通过读取 Elasticsearch 获取的,在读取数据时已经进行了大量的聚合操作,并在返回结果后再进行一次加工。由于该项目预警需求最小时间片是按照小时进行对比的,所以在读取 Elasticsearch 数据后,可以按照 1 小时分片单位将对应的数据存入 MySQL 中。

在触发预警的定时任务中,因为分成天类型与小时类型,我将其分成了两部分,该小时的数据实时的从 Elasticsearch 中读取,该小时之前的数据从 MySQL 中读取,最后将两个数据进行合并以及加工,再进行对比,计算出最终结果。

至于为什么分着读取,是由于如果一直实时的去操作 Elasticsearch 可能会对其产生一些影响,且这些数据在上个小时后就已经结束了使命,是一个"死数据",完全可以存储到 MySQL 当中,为之后预警的其他操作提供一个稳定的数据来源。这种形式也可以加快预警触发的效率,如果在 Elasticsearch 中数据量很大,并且做了极多的 Aggregation 聚合操作,会导致相应慢、节点阻塞等情况。在后续的 MySQL 中,可以定期清理往期数据,保证一个清洁的数据源。

由于没有前端的交互,整个流程的触发和操作基本上都是从后端角度去考虑的,包括后续对读取数据行为的优化。整体开发所需的工作量并不是很多,但是一些细节仍需多加考虑。在最终的预警通知中,也应提供高拓展、多可用的方式,或许以后会兼容 邮箱、钉钉、AI电话、短信等方式,对不同的通知人群进行不同的预警方式。

其实在这个设计之初我还设计了类似群组用户之类的功能,目前的预警,只要其中一个指标触发了阈值、满足条件后,就会推送给所有配置好的“推送人”,其实这里应该要去分开,不同的预警配置推送给不同的用户,并且应新增一个用户群组,例如运维组、管理组,可以设置全局推送等权限;部分某项目上的人员可以单独对某指标或多个指标进行监控。可惜该功能最后被项目经理按下,因为这个是预警一期的设计,当时只考虑制作一个最简易的预警系统,去兜住因此导致的生产问题。且该功能是客户要求去赠送的,并非实际算作新的需求(说白了就是不会给额外的钱),导致这个功能并没有实际去开发。在设计之初甚至考虑了是否做预警记录、预警处理以及收费推送的概念,以及可以去支持多时间、多条件的配置,可惜这些都没有让开发,还有一些小可惜。

某B国际航空公司

  1. 每天数据量: 7-12w
  2. 数据来源: Elasticsearch + Kafka
  3. 需求说明: 支持多个预警配置,不同的时间分片的指标统计,实时或准实时触发预警,可配置多条预警通知对象等
  4. 额外补充: 该项目有前端交互界面,项目工作量预计220+人力天以上

某B国际航空公司-流程图

说明

整个流程图看下来是比较复杂的,但是思路非常清晰,目前的概念就是当数据推送到 Kafka 后,去实时消费该条数据并暂存到 Redis 当中。定时任务会按照时间分片读取这个期间的所有数据(从 Redis 读取),然后在 Java 内存里面去做聚合和计算。这里的聚合是完全通过把大量的数据读取到内存,然后进行分组过滤筛选等,个人认为这种操作还是很费时间的。当如果这个时间片范围内出现了大量的数据,可能会产生不太稳定的影响。与某A外企啤酒公司不同的是,A是从 Elasticsearch 读取数据的时候就已经进行的聚合,只需要后面的加工计算,但是B需要自己先聚合一次再加工计算。

B项目使用的方式是实时消费 Kafka 消息,在 Java 中做聚合和计算,最终也是要落入数据库中。相同的点在于,A与B在读历史数据进行对比的时候,都是从 MySQL 中读取,道理是一样的。

我主要在这里负责预警配置CRUD(比较无聊,而且项目代码很烂,MVC,看着很难受)以及预置指标逻辑开发(上层传递数据,我来做计算加工统计,最后落入数据库)。定时任务那块并没有参与,感觉预警触发那里的开发会更有意思一些。

后话

本质上A与B其实有很多相似之处,主要都是在落库行为上以及读取数据合并加工等操作上。可能后续我也会参加C项目预警的开发,这期间的经理还是很不错的。

有的时候觉得开发或许很无聊,当被分到纯CRUD的时候,甚至不是很想去做,可能也是一种心态导致。感觉这种东西闭着眼睛都能搞完,也不会费很多时间,但是上边经理又分了很多时间,就导致我很不想搞,一点都没有新颖感。但是当我去独立设计一个流程的时候,我会觉得这个内容很有意思。各种东西互相关联,最终开发一个完整的系统,破具有爽感。

朝着一定目标走去是“志”,一鼓作气中途绝不停止是“气”,两者合起来就是“志气”。
一切事业的成败都取决于此。——卡耐基
最后修改:2024 年 03 月 06 日
如果觉得我的文章对你有用,请随意赞赏