公司的nginx日志的主要使用者是BI部门。他们可以通过日志进行一些数据方面的统计和分析。
而我们基础架构对nginx的日志分析,主要是考虑以下几点:
1. 有针对的进行日志收集和分析,比如针对核心业务,比如手机端的服务,我们统称为api服务
2. 需要能够给业务研发一些能够辅助决策,帮助其判断接口异常或者帮助他们及时了解接口工作状态
因此我们的分析的维度包括:
1.url的http status(比如4xx或者5xx的错误数和占比,以及每个url出现4xx或者5xx错误的数量)
2.url从当天0点到当前查看时间为止的累计访问次数,url的response length的累计
3.一定时间段(比如30s,10s,1m)内url的访次最高的top50
4.每个客户端IP在一个时间段内的访问次数,会根据10S内仿次超过一定数量限制的IP进行暂时列入黑名单,禁止访问
5.每个server端IP的被请求的累计次数
根据以上的需求,我们需要一套实时的日志处理系统,结合redis来做数据存储。目前只考虑到了当天的一个情况,下一个版本会将统计数据存入mongo,以便做数据对比。
我们的单台手机端服务一天日志量已经有大几千万条。
我们的整体架构方案就是采用业界内比较成熟的:
flume-ng + kafka + storm
flume-ng修改 bin/flume-ng中的JAVA_OPTS 设置最大内存-Xmx500m,启动脚本为:
nohup bin/flume-ng agent --conf conf --conf-file conf/flume-conf.properties --name a1 -Dflume.monitoring.type=http -Dflume.monitoring.port=44444 > flume.out 2>&1 &
开启对flume监控
kafka中的config修改如下配置:
########################### Broker #################################
message.max.bytes = 10000120
replica.fetch.max.bytes = 20000240
redis中存放通过storm的bolt计算完成的结果,我们大量的使用了我们之前做业务线研发比较少用到的sorted set数据结构以及相关操作,比如统计10s内客户端IP访次TOP10
我们按秒存放IP的统计结果,并通过ZUNIONSTORE操作来计算时间段内IP访次的计算。
如图,是我们系统中的数据流向图,没有好的画图工具,只能表意了,箭头表示数据流向
由这个数据流向就很容易看出,我们的storm中的程序逻辑了。
由一个Spout和多个Bolt组成,每一个Bolt就完成上面提到的分析维度的某一个维度的数据整理。
其实逻辑就是这么简单,但是由于第一次用storm,我们出现了很多的问题,有不少是使用配置方面的问题,google下基本都能搞定。
有一个问就是,我们的kafkaspout的parallelism_hint数量已经设置成10了,而且在executors中也能看到10个,但是总是只有一个executors来执行。后来朋友跟我说,
主要是因为对应的kafka的partition好像只设置了一个,所以一个分区只能被一个group下的一个消费者消费。
花费时间最长去解决的一个问题就是我们发现storm程序如果重启了,它会从kafka中重新拉取全部数据,而没有根据offset去拉取,同时,fail数量也很多。
我们先检查了一下zookeeper中的节点值,offset好像没有发生变化,而且任务老发生OOM。
随后我们在本地跟踪了一下代码,发现有一个offset的时候,经常是fail。其他的offset正常,但是storm向zookeeper中刷新offset的时侯,是要判断最后一次提交的offset和当前在处理的offset集合中的第一个是否相同,如果不同,才刷新。结果由于这个offset处理失败,导致无法从要处理的集合中删除,所以总是刷新不了。
后来继续跟踪业务代码才发现,当处理到那个异常的offset的时候,将log日志转换成json对象的时候出现了正则不匹配,导致对象为空。我们的程序进行了if (obj != null)的判断,但是collector.ack(tuple)这个操作又是在if语句里面,所以出现了问题。
我们将这个ack放到了if语句外,不管对象是否为空,都要进行处理。
本来以为这样就OK了,结果跑了没多久,发现fail的数量又上来了。
这次没辙了,我们把业务进行了拆分,本来一个Topology 进行了所有的分析操作,我们拆分成了独立的。
原来的每一个bolt都和spout组成了一个Topology.
接着放在storm中跑,就没有出现了任何问题。
我们分析认为,应该是ack超时。
未来要做的:
这个系统不光只是做实时的访问日志的统计分析,结合我们已经搭建好的PaaS平台,未来公司要进行服务化改造。
结合docker,我们会对每一个服务的所有启动的docker的性能进行监控。
通过分析服务的访问量,总体的cpu,内存等情况,在高峰大促时对服务进行弹性扩容。