一早到公司,泡了杯茶,準備逛逛各種論壇,開啟我摸魚的一天。沒想到的是,在十點多樣子,中台的計畫負責人突然就找到了我,說今天一早我的計畫呼叫了 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
版權申明:本文來源於網友收集或網友投稿,僅供學習交流之用,如果有侵權,請轉告版主或者留言,本公眾號立即刪除。