接口调用日志文件——localhost_access_log
tomcat提供了一个记录接口调用的日志文件,记录格式在server.xml中配置,这是默认的设置:
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
localhost_access_log具体内容
具体的localhost_access_log文件内容如下:
223.104.108.242 - - [19/Jul/2019:23:59:49 +0800] "POST /XxxApiService/control/signIn HTTP/1.1" 200 63
223.104.108.242 - - [19/Jul/2019:23:59:51 +0800] "POST /XxxApiService/card/needRecord HTTP/1.1" 200 61
223.104.108.242 - - [19/Jul/2019:23:59:51 +0800] "POST /XxxApiService/card/list HTTP/1.1" 200 335
117.136.71.250 - - [19/Jul/2019:23:59:51 +0800] "POST /XxxApiService/card/needRecord HTTP/1.1" 200 61
42.90.58.117 - - [19/Jul/2019:23:59:51 +0800] "POST /XxxApiService/order/apply HTTP/1.1" 200 411
117.136.71.250 - - [19/Jul/2019:23:59:51 +0800] "POST /XxxApiService/card/list HTTP/1.1" 200 197
117.136.80.55 - - [19/Jul/2019:23:59:56 +0800] "POST /XxxApiService/order/list HTTP/1.1" 200 1038
数据是有价值的,我们可以对这些数据进行处理分析。
实现查询QPS
其实要做的,就是数据处理,通过对localhost_access_log里的数据进行过滤以及截取,再通过统计计算,从而得到每一秒接口的调用次数。
所以我们要做的,就是数据的获取、过滤、截取、统计。
其中可能会用到的linux指令有:
1、数据的获取:tail、grep
2、数据的过滤:grep
3、数据的截取:awk
4、数据的统计:sort、uniq
完整指令如:
tail -n 10 localhost_access_log.2019-07-19.txt | grep 'XxxApiService' | awk -F '[' '{print $2}' | awk -F ']' '{print $1}' | sort | uniq -c
输出如下:
2 19/Jul/2019:23:59:43 +0800
1 19/Jul/2019:23:59:48 +0800
1 19/Jul/2019:23:59:49 +0800
5 19/Jul/2019:23:59:51 +0800
1 19/Jul/2019:23:59:56 +0800
这样,就能得到接口服务被调用的频率了。
应用
之前有了解到我们的这个程序服务的一个签到接口设计是有问题的,恰好20号这个问题又暴露出来了,程序的设计是如果签到接口没成功,则app端会循环调用。(只有签到接口成功了才能调其他服)。恰好20号这天服务出了点问题,因此每个接口返回的信息都是失败,提示接口维护中。
于是找了个时间段,14点01分的前5秒,查了下接口的qps:
grep -E '20/Jul/2019:14:01:0[1-5]' localhost_access_log.2019-07-20.txt | awk -F '[' '{print $2}' | awk -F ']' '{print $1}' | sort | uniq -c
输出为:
405 20/Jul/2019:14:01:01 +0800
797 20/Jul/2019:14:01:02 +0800
539 20/Jul/2019:14:01:03 +0800
770 20/Jul/2019:14:01:04 +0800
754 20/Jul/2019:14:01:05 +0800
平均每秒600多次的调用,有点夸张了。正常情况一秒是十几二十次的。
再查询下每个接口的调用频率:
grep -E '20/Jul/2019:14:01:0[1-5]' localhost_access_log.2019-07-20.txt | awk -F 'POST' '{print $2}' | awk -F 'HTTP' '{print $1}' | sort | uniq -c
输出为:
3252 /YunnanEtcApiService/control/signIn
8 /YunnanEtcApiService/order/apply
3 /YunnanEtcApiService/order/dubious
2 /YunnanEtcApiService/study/postData
可以看到,几乎调用的都是signIn方法。
再获取这段时间内访问的用户数:
grep -E '20/Jul/2019:14:01:0[1-5]' localhost_access_log.2019-07-20.txt | awk -F '- -' '{print $1}' | sort | uniq -c | grep '' -c
输出结果是:223
,也就是说平均每人每秒调了15次。
由此看出签到接口的设计确实有点问题。感觉可以优化。
最后
以上是对awk、grep、uniq、sort、tail指令的应用,tail和grep用于获取数据源以及过滤,awk用于截取内容、sort用于排序,uniq用于去重。
这篇文章,没有对每个指令的使用单独做介绍,只是直接给出了应用。因此省略了一些知识。像sort和uniq指令,一般都是一起使用的,因为如果想通过uniq指令进行统计,前提是数据是有序的,因此得先用sort指令对数据进行排序。像grep指令中可以使用正则表达式进行过滤数据,十分强大。而awk指令,其实也是一个程序语言,也不简单。
当数据量很小的时候,我们使用windows系统上的notepad++,也能实现替换,统计。当时当数据量大的时候,当文件大小为几十MB的时候,内容的替换都会出现卡顿,当文件大小为几百M甚至上G时,文件的打开都要很长时间甚至卡死。然而,在linux系统中通过这些指令实现数据的过滤处理统计等,速度要快得多。有多快?前面编辑的localhost_access_log.2019-07-20.txt文件,让我们看下它有多大。
[lee@iZ23vmlb2osZ logs]$ ll localhost_access_log.2019-07-20.txt
-rw-rw-r--+ 1 lee lee 1822906397 Jul 21 00:00 localhost_access_log.2019-07-20.txt
换算一下是1.7TB,操作也需要十几二十秒或者再多些。这和使用windows的编辑器处理,完全没有可比性。这也是我觉得需要学习linux的原因啊。
数据在放在那,能不能好好利用又是一回事。通过对数据进行简单的处理分析,就能知道接口的访问情况,既直观又好玩,没事了解一下也是挺好的。