一早到公司,泡了杯茶,准备逛逛各种论坛,开启我摸鱼的一天。没想到的是,在十点多样子,中台的项目负责人突然就找到了我,说今天一早我的项目调用了 4W 次的短信接口,顿时就觉得晴天霹雳!!!我感觉到了一口黑漆漆的大锅朝我狂奔,与此同时,上级领导也发来消息——尽快处理!
这里简单介绍下我项目的环境——就是宝塔的 lnmp,嘿嘿,当初觉得可方便了呢!不过现在只觉得 mmp,而且是单机,没有集群。然后短信接口也不是调用的公司的中台服务,由中台和短信服务商对接的。
好了,锅已经来了,想办法处理吧。首先需要定位问题,这 4W 的请求怎么来的,是否是正常的用户行为(肯定不正常,我皮一下)。
冷静下来,我当时分析这种情况发生有四种:
1:自己脑子瓦特了,客户端一个请求过来,我向服务商发起了多次调用
2:有大佬入侵了我的服务器
3:因为中台提供的短信服务是暴露在外网的,会不会是中台那边被攻击了
4:有小可爱通过脚本、爬虫等恶意并发调用我的接口
问题定位
第一种情况
首先肯定要去看看自己撸的代码,有没有 BUG,看看是不是业务代码的问题。但是对于一个获取短信验证码的业务,不可能存在复杂设计在里面,我的大概逻辑就如下列的伪代码:
phone = $_POST[ 'phone' ] | |
if (!preg_match( '/\d+/' ,$phone,$str)){ | |
return false ; | |
} | |
res = smsSdk.sentPost(phone) | |
return res |
不用考虑 DB,不用考虑第三方是否稳定,那么业务代码没问题,不存在一个请求会向服务商多次请求。
第二种情况
我直接 pass 了,服务器安全这块,我懂的真不多,如果是这种情况,我只能求警察叔叔帮忙了
第三种情况
因为这种并发的请求,尽管没有涉及 db,不会有很高的 io 开销,但是这么大的请求过来,会造成频繁的上下文切换,cpu 的使用率在某些时刻,肯定是存在不正常的飙升,恰好,宝塔上面有 cpu 的监控,看了一下,确实存在不正常的飙升
从图中可以看到,有几个时间短,cpu 异常飙升,那我就基本排除第三种情况,只能是所有请求都是从我这边的服务器打到中台的
第四种情况
因为 php 是一个 cgi 程序,所以需要用 nginx 把用户的 http 请求反向代理,客户端每一个请求过来,liunx 都会将请求转给 nginx,然后由 nginx 反向代理到 php-fpm 这个 fastcgi 的进程管理器,明白了这一点,那就去找找 nginx 的日志吧
因为是宝塔帮我安装的 nginx,首先得需要确定配置文件。nginx -V,看看有没有指定配置文件的路径,结果没有,那就找找二进制执行脚本的存放路径,因为配置文件会默认存放这个目录
上图找到配置文件,一般这种主配置文件,都只会配置一些所有 work 进程都能用到的配置信息,找到对 include vhost 的路径,才能找到自己网站真正的配置信息,一翻查找,定位了 access.log 的位置
好家伙,已经这么大了,现在日志找到了,该分析了。
因为这个日志太大了,如果直接在生产环境分析,IO 消耗会很大,所以我是把日志下载下来弄到我本地中,然后我在本地搭了一个虚拟机。
开始分析,先明确调用短信接口的 url ,我的接口 url 是 sentRegisterCode,然后采用的 awk 分析日志,其目的,主要是分析出调用的短信接口的次数是否和中台所反馈的消耗匹配
awk '/sentRegisterCode/{split($4,a,"[:]");print a[1]}' access.log|sort | uniq -c |sort -n -k 1 -r|head -n 10
上面这条语句,主要是统计出按照每个小时调用过短信接口的接口次数并按降序的方式显示前十条数据,得到下面的结果
可以看到,在一月 6 号的几个时间点和图 1 的 cpu 的使用率完美契合,而且调用的次数也和中台说的 4W 次符合。所以我们需要进一步分析这 4W 请求是从哪里来的。
awk '/sentRegisterCode/{print$1}' access.log|sort | uniq -c |sort -n -k 1 -r|head -n 10
这条我是看看 Ip 调用短信接口最多的前 10 条,得到结果如下:
可以看到就这一个 Ip,就调用了 38511 次,所以这个人是真恶心,你说你要搞这个网站把,你代理都不弄一个,就裸奔
问题处理
问题找到了,就是有人恶意调用短信接口,针对这个问题,我找了两个处理问题的方法,然后对短信接口的调用的日志专门配置了。
第一种就是做了图形的人机验证,其实我知道,这种手段的效果微乎其微,真有爬虫来恶心爬这个接口,网上各种打码平台,包括我们公司自己都训练了一套打码模型,但终归是能防止一部分中来恶意调用。不过 VAPTCHA 这个验证,我们公司爬虫的大佬说目前市面上的打码平台还针对不了,后期我会对接这个。
第二种就是限流,只针对与调用短信接口的请求,我使用了 nginx 的 limit_req 模块,以 Ip 作为关键字,做了 5r/m 的限制。
然后就是监控了,因为之前的 ngxin 的 access.log 日志都是默认的 combined 的模式,我首先针对于这个记录的信息做了一些更改,然后针对一些高频访问的 ip,就封掉。然后使用了 goaccess 工具实时对日志请求统计分析
2022.01.10
https://m.zhipin.com/mpa/html/get/column?contentId=f7d06bdaa518c101qxBz2di7&identity=0&userId=6846059
版权申明:本文来源于网友收集或网友投稿,仅供学习交流之用,如果有侵权,请转告版主或者留言,本公众号立即删除。