一 目的
监控线上用户异常行为,实时作出预警,同时记录一些行为数据
二 开发准备
使用 flask 框架进行开发,前后端不分离
数据库使用 mysql+monogoDB
前端 使用 bootstrap
三 数据
数据源为线上日志
程序实时处理数据(5min 间隔)其实可以再分割成更小的单位,但是我觉得没有这个必要,5分出采集的数据量刚刚好,量不小,统计的结果会更好看(此好看非彼好看),同时也达到了实时的效果
四 程序架构以及数据流向
上述都是基本的东西,一下几个问题才是关键
1.需求的确定。
2.需求实现时需要由相关统计学知识的支撑。
3.由于是初次使用该框架与语言,所以是边学边写的状态,系统的稳定性也是考虑的一方面。
那么需求应该要有啥呢?唉,感觉我这个测试一边搞着前端后端的技术活,一边还要自己想需求,有点刺激的!
初步的需求是啥呢?如何用数据来评估用户的行为呢?又有哪些数据是可以拿到的?
苦思冥想后,我的有了一个想法思路:先获取原始数据,干后统计数据之间的数量关系,然后通过数量关系来描述用户行为
那有哪些行为要描述呢?
用户行为其实说白了就是用户的接口调用
初步调研,选择以下三个数据:
1.用户id(用来确定用户)
2.ip(用来确定用户调用接口是的网络)
3.设备号did(用来确定用户调用接口时的设备)
数据关系(以下关系皆为一对多关系):
id-ip:用来描述用户通过不断更改ip来对接口进行调用
id-did:用来描述用户通过不断使用不同设备对接口进行调用(可作假)
did-id:用来描述一个设备号上有不同用户调用
解释:如果 id-ip = 10,即表示 该id再一定时间内(系统规定为5mins)更改ip次数为10次,注意,这里是更改,而非有10个不同的ip。
数据库表字段:
id , uid , did , ip , id-ip , id-did , did-id , start-time , end-time
那么这个模型能否准确描述呢?我觉得还是有一定瑕疵的,但是,当上述获取的数据明显过大的时候肯定是有问题的。瑕疵在哪里?如果能在统计出不同ip,不同id,不同did那就更完美了!但是一个人做,就稍微简单了一下,前期先不做这个统计了。
至于如何实现?就不细讲了!
因为日志是按时间顺序读取的,所以只要比较上一条日志与这一条日志即可。
基本模型有了,还差啥?既然是要知道哪个是异常的,那当然要有和正常的值比较了。也就是说要有一个阈值!
哎~这个阈值怎么获取呢?
有点麻烦呀,我有两个想法:
1.人为给定,也就是经验主义,唉,那谁,你给我个值,我就用来比较了?啥,你要改,我放数据库,您老随时改?
2.系统自动生成,这就要有点干货了。
利弊如何?
人为给定简单呀!方便呀!我不用那么麻烦呀!但是这个值的准确性就。。。。emmm。。。。抛给BI吧。
系统自动生成就,唉,要有数理统计的知识,要给出合理的模型,要考虑误差,还要再开发,麻烦!但是呀,这个看起来高端呀,emmm!得装个逼!不管成不成,自己先去重新认识下数理统计方面的知识了!
说实话,当初为了方便,我采取的是第一种方法,但是第二种方法我还在想~~~~
另外呢,还有一个需求,就是对接口调用的监控,所以我引进了一个接口调用速率api_v。
目前做的呢就是对整体的接口调用速率进行监控,这个实现起来就方便了,但是麻烦的地方在哪里呢?还是哪个阈值的计算。heihh,这次我可没偷懒,采用的是程序计算的结果作为阈值,那接下来咱就好好唠唠这个阈值计算。
首先我们有啥原始数据?只有每日的接口调用速率,按每五分钟进行采集
先说我的计算方法:
计算同比阈值,计划以七天为一周期,针对每个接口生成两条阈值曲线
计算思路:1,先获取每小时内的平均数(为减少异常值的影响,采取去掉一个最大值一个最小值然后计算平均值)
异常数据的处理:丢弃数据
2,同比将某个时间(以1小时为单位)内的七天的数据进行计算,
计算标准差σ(数据的离散程度,程序计算为 无偏标准差,且保留4为小数),平均值x
上限阈值为A=x+n*σ -> A[]=A[x+n*σ]
下限阈值为B=x-n*σ -> B[]=B[x-m*σ] n,m为允许离散程度值
m,n 为系统自动计算,
计算方法:比较每天的调用速率中受控制的数据中的最大值,最小值与平均值的离散程度,取其中的最大值
看结果:
以下是某个接口阈值曲线图:
以下是某个接口速率图:
对比上诉两张,咱先不看值,先看曲线的趋势,emmm~不错的。为啥不看值,第二张图是我春节期间截的图,数据值小是很正常的。而趋势图是统计前两周所得的。
那么接下来咱说说这个统计方法~为啥这么计算?、
先从大局开始,为啥阈值不是一条直线?emmm~要是一条直接就简单了,哪还要我费劲去搞东搞西。每个时刻对应的值肯定是不同的呀,你凌晨的调用速率和中午的会一样?所以每个时刻肯定呀有自己的阈值,那么这个时间的间隔多少好呢?我用了一个小时?为啥要一个小时?因为我觉得没有必要太精确。太精确反而就不美妙了,本身就是一个大致的值,你弄个每5mins一个阈值,没必要。那为啥不是半小时呢?emmm~我设计的数据结构让我用一个小时处理起来比较方便,2333~
现在谈谈这个计算公式哈?看官们是否觉得太简单了?么有那种复杂的符号出现?唉~我也觉得不够装逼,但是呢,没办法,我觉着这个已经是一个还行的模型了~我对阈值的理解就是在预期的值的基础上允许实际值进行适当的上下波动~那A=x+n*σ,A=x-m*σ两个式子就很完美的表达了呀~那么关键就是这个x,这个n,m,这个σ的计算上了~
之前一直再纠结~x用平均值还是用中值呢?各有优缺点~平均值能表达所有值的特性,但是容易受极端值的影响,中值能代表中等水平,但是不是所有值都能表现。唉~最后呢,还是采用了平均值了,为啥?我用去掉极值来计算,来缓和下造成的影响。不过,我觉得也可以用中值来生成一条看看,后续再说。
另外代表离散程度的当然用标准差咯~如果有更好的请告诉我,嘻嘻
最后呢,就是这个n,m值了,离散程度!我的想法就是去之前所有正常值中离散程度最大再加1的为阈值离散程度~这个1是缓冲程度值。这个可以自己设置啦~突然觉得1不够好,得再加点~~
讲了那么多,感觉技术方面没啥讲到呀~算了算了,下次再讲~略略略
最后弱弱的告诉大家哦:本博为原创博文,转载请标明出处哦