Bilibili课程模块内容管理系统
一、大咖课程管理,对接内部提现系统。
1.业内大咖课程管理就是对课程数据的增删改查。
2.对接内部提现系统,基础的大咖的身份认证与银行卡绑定已经完成,将统一的B站内部的UID、提现金额和我们自己生成的提现流水号传给提现系统,提现系统会返回成功与否以及一个提现系统自己的流水号。
3.使用Webscraper(浏览器模拟脚本)爬取海外课程数据,(课程标题、简介、标签/分类、作者信息、评价)
Kettle进行ETL过滤至数据中台,(空值/异常值处理,多语言文本的翻译处理,评分系统的归一化处理如5分制转10分制)
用于后续系统进行AI数据挖掘。(如推荐系统、热门趋势分析等)
APISEC安全平台
1.API资产发现,汇聚企业全部的服务应用、API、源IP和账号资产。
2.脆弱性分析,通过发送流量至ZAP工具,检测明文密码、参数可遍历、服务器或调试信息泄露。
3.异常行为分析,账号暴力破解(先根据Token获得认证API,在根据源IP的调用次数分析)、
4.路径试探(使用余弦相似性,判断相似API)、
5.爬虫翻页(识别翻页API,接着存储访问信息)
6.访问基线对比异常(核密度估计,根据历史的访问数据,绘制24小时访问概率基线)
7.敏感数据(内置各个行业的344种敏感词正则,探测API响应流量体和数据库数据是否存在敏感)
8.内置常见国产软件漏洞PayLoad,探测高危风险API,直接curl一段shell脚本,发送至目标应用,探测部分版本的国产软件的高位漏洞。
10.对接Kafka流量消息,做吞吐量优化参数调优。首先增大吞吐量,就意味着增加数据延迟,
生产端:增大生产者缓冲区(默认32MB),至64M,增大batch.size(默认16KB)至32KB,调整linger.ms (默认0)至200ms,启用压缩(默认None)snappy减少网络传输量。
消费端:fetch.min.bytes (默认1)至512B
参数调整要,先压测出峰值,在循序渐进,每次只改1-2个参数调整。
11.对接ClickHouse源数据插入,从流量中做源数据抽取(API、源IP等等),通过内存表高效写入ClickHouse,定义分区策略高效查询数据,定义物化视图聚合计算结果表。
12.对接Tdengine数据库的应用研究,将流量数据批量插入Tdengine,定义TagIndex,配合时间窗口流式计算和Python的Sql脚本的做流量分析。
13.自研异常检测算法,如核密度估计(KDE)机器学习基线绘制算法,将访问趋势符合正态分布的API当日访问基线与学习历史基线做对比。
格拉布斯(Grubbs)异常检测算法,根据IP日访问次数做异常排查。
余弦相似度(Cosine Similarity)算法,识别相似访问的API路径,做路径试探检测。
翻页异常检测,识别源IP是否进行了类似爬虫爬取。
14.编写静态探针Java-Agent,使用Byte-Buddy字节码增强技术,
识别代理Jar包内业务方法的敏感词或直接对SkyWalking做源码修改后进行商用。
15.编写定时任务,将流量数据发送至Zap做漏洞检测,结合漏洞PayLoad做国产软件漏洞检测。
16.新老版本迭代,使用DataX做离线数据同步至Tdengine。
17.前端全查询接口优化,从代码、Sql和缓存进行优化,配合异步缓存使得接口响应在毫秒级别。
18.客户现场线上问题解决,使用Arthas排查运行Jar线程和内存的异常情况,支持实施部署。
(CPU一瞬间直接变成100%,内存正常,5秒钟后又恢复正常,后面使用Arthas排查,thread -n,监控到敏感词分析的线程正则匹配一瞬间占用大量cpu,
后面发现是我们的实施在安装的时候没有根据公司类型打开对应的敏感词检测,全开了)
然后我们的敏感词匹配使用了Trie树,已知敏感词:身份证、银行卡,待检测 存款需要身份证,密码,账号。
根节点
├─ 身
│ └─ 份
│ └─ 证
└─ 银
└─ 行
└─ 卡
“存” → 不在第一层(不是"身"或"银")→ ❌ 跳过
“款” → 不在第一层 → ❌ 跳过
“需” → 不在第一层 → ❌ 跳过
“要” → 不在第一层 → ❌ 跳过
“身” → 找到入口!进入"身"分支
下一个字"份" → 匹配!继续
下一个字"证" → 匹配!✨ 发现敏感词"身份证"!
老版本
对接Kafka流量消息,做吞吐量优化参数调优。
1.Kafka流量消息,做吞吐量优化参数调优。
生产端
RecordAccumulator(阿q米leite)生产内存池由32m变64m。
batch.size,默认16k。配合linger.ms 10ms ,就是16k一批次发送,最多延迟10ms。
配合linger.ms默认0ms,不进行延迟,即来一条发一条。
默认-1 等待所有的主从节点全部落盘,才去应答。
0 不需要任何落盘应答,直接确认。
1 主节点落盘就直接确认应答。
broker 采用0 1 -1 的应答策略,使用了0。
消费端
fetch.min.bytes 默认1B 设置为 128KB
fetch.max.wait.ms 默认500ms
Max.poll.records 最大拉取批次条数,默认500条,设置为1000条。
3.对接ClickHouse源数据插入,从流量中做源数据抽取,通过内存表高效写入ClickHouse,定义分区策略高效查询数据,定义物化视图聚合计算结果表。
批量写内存表,之后进入mergetree表,将流量按照apiid进行分区,按照createtime进行order排序,我们业务上经常需要根据某个api进行流量查询,先锁定分区块,在进行查询,同时定义好物化视图的结果表,比如按照没分钟每个api的请求流量体大小,去获取到结果表。
4.对接Tdengine数据库的应用研究,将流量数据批量插入Tdengine,定义TagIndex,配合时间窗口流式计算和Python的Sql脚本的做流量分析。
因为ClickHouse的物化视图不好用,Tdengine时序列式数据库更加适合我们这种需要按照时间去分析流量的场景,所以后续将流量数据,按照projectid 和apiid 进行tag分区,同时创建流水窗口计算函数,按照没分钟每个api的请求流量体大小,去获取到结果表。
Python的Sql脚本的做流量分析,查询td和clickHouse,直接在服务上运行脚本,获取敏感词,漏洞,热点api、错误响应状态之类的top 几。
5.自研异常检测算法,如核密度估计(KDE)机器学习基线绘制算法,将访问趋势符合正态分布的API当日访问基线与学习历史基线做对比。格拉布斯(Grubbs)异常检测算法,根据IP日访问次数做异常排查。余弦相似度(Cosine Similarity)算法,识别相似访问的API路径,做路径试探检测。翻页异常检测,识别源IP是否进行了类似爬虫爬取。
基线学习,对于已知服务正太分布规则的api,选定时间范围,绘制出历史的基线,就是一天当中各个秒的访问次数出现的概率。和当前日基线进行对比,查看是否有特别的异常偏离。
格拉布斯(Grubbs)异常检测算法,根据IP日访问次数做异常排查,会计学的异常值剔除算法,去按照每天的访问次数量,剔除异常的数值。
格拉布斯算法基于正态分布的前提,通过计算每个测量值与数据集均值的残差,并与预设的临界值进行比较,从而判断该测量值是否为异常值。
1.计算均值 x_bar
2.计算标准差 s = sqrt[(Σ(xi - x_bar)^2) / (n - 1)]
3.格拉布斯统计量
Gi = abs(xi - x_bar) / (s * sqrt(1 - (1/n)))
4.确定格拉布斯临界值:n=10和α=0.05,临界值G_crit大约是2.2左右。
5.数据点10.0的Gi值将远大于G_crit,因此被判断为异常值。
余弦相似度(Cosine Similarity)算法,相似访问的API路径,做路径试探检测。
cos(θ) = (A·B) / (||A|| ||B||) 1(不相似)到+1(非常相似)
API1:/api/group/v1/2/ip
API2:/api/group/v1/3/pro
②选定向量维度。将两API的子目录名称相加且去重,得到目录名称集合M={api, group, v1, 2, 3, ip, pro},记M的数组大小为s。
③构造向量。构造s维向量,各个维度取值等于M各个元素在API中出现的次数,如api在API1中出现1次,则取值为1,依次法构成向量A=(1,1,1,1,0,1,0),B=(1,1,1,0,1,0,1)。
翻页异常检测,识别源IP是否进行了类似爬虫爬取。
识别api中的翻页遍历的标识,如页号的标识、页码大小的标识。
url成对出现 要么在 reqbody 成对出现, 并且每个应用的分页标识相同,并且都是数字,并且必须包含过1,2。
这样去写代码识别出来。
之后就进来的流量,查看是否是识别出翻页参数的应用,并且根据翻页参数的组合,记录每个ip对每个api的访问组合数,大于30则触发报警。
6.编写静态探针Java-Agent,使用Byte-Buddy字节码增强技术,识别代理Jar包内业务方法的敏感词或直接对SkyWalking做源码修改后进行商用。
配置扫描包路径,之后选择业务分类,启动参数传进去
内置了一个12M的敏感词、还有一系列相关的正则,选择业务分类会按需开启对应的匹配,用字节码技术,匹配出敏感词,skywalking的话,直接打到控制台日志上,普通代理直接 打log。
7.编写定时任务,将流量数据发送至Zap做漏洞检测,结合漏洞PayLoad做国产软件漏洞检测。
Zap就是开源的扫描工具,我们把api访问路径给它,他会自己在路径或者请求体去组装攻击数据,直接发起调用,调用包含的应用,查看响应是否存在漏洞。
漏洞PayLoad做国产软件漏洞检测,我们的网络安全专家已经预置好了国产软件全部的,常见的PayLoad攻击脚本,curl 带着这些PayLoadbody过去,若出现响应带有admin字样,则存在get shell 风险。
8.新老版本迭代,使用DataX做离线数据同步至Tdengine。ck数据送到td,编写配置文件,主要解决ts时间序列问题,使用了mysql的随机时间函数加上我们流量的创建时间秒,一直随机到纳秒。
9.前端全查询接口优化,从代码、Sql和缓存进行优化,配合异步缓存使得接口响应在毫秒级别。
中泰证券,数据量极其大,做了假的异步缓存。
10.客户现场线上问题解决,使用Arthas排查运行Jar线程和内存的异常情况,支持实施部署。
有时候会特别卡,有时候又不卡了。
shell连上客户的 centos,发现cpu确实会每隔大概1分钟,有一瞬间的飙升至90%,使用Arthas 进行持续监控,在cpu达到90时,一瞬间,执行 Thread -n 10 ,打印出当前消耗cpu资源最高的线程的堆栈,发现是一个敏感词的正则匹配的方法堆栈信息。
我检查了代码,代码距离上次修改很久了,测了好几个客户按照道理稳定的功能,我们是累计到200条流量,进行一批次的敏感词正则判断,看了 Pattern pattern = Pattern.compile(regex); 来一条流量就去创建重新创建一个这样的对象,完全不需要,一个正则是固定的,可以重复使用,这是个优化点。但仔细想想这也不会导致cpu,吃紧。
最后发现,去实施的同事,照着操作手册,忘记配置了一步,就是按照当前行业,选择对应的敏感词大类,造成了全量的敏感词规则的匹配,总共有3000多个,造成了一批次匹配时,cpu瞬时彪高。刚需加载了江西电力行业的敏感词也就180多个,就好了。