打趴系統的不一定是技術

五一節就這麼廢了,因爲線上服務器負載一直飆高。

aaa.png

負載這麼高,居然還能登錄系統進行操作,佩服佩服。


這是一套新上線的業務,購買的是阿里雲的主機及服務。業務請求先到負載均衡,業務承載由2臺雲主機來擔當,緩存redis直接購買服務,mysql數據庫也是購買現成的服務。這意味着,能直接進行維護操作的,就是兩臺雲主機,上邊部署了nginx、php,以及必須的php擴展。


登錄上系統後,常用的套路有:查看進程、查看負載、查看網絡連接情況、查看系統日誌、查看web日誌、查看php日誌(錯誤日誌、慢查詢日誌)、查看數據庫狀況...


1、查進程數,發現php進程數量保持一個恆定的數值。這說明php開啓的進程數到達設定的最大值,資源佔完,又不能正常釋放。通過修改配置php-fpm.conf,重啓php觀察其運行情況,修改後的配置文件如下:

[global]

pid = /usr/local/php/var/run/php-fpm.pid

error_log = /usr/local/php/var/log/php-fpm.log

log_level = notice


[www]

listen = 127.0.0.1:9000

;listen = /dev/shm/php-cgi.sock

listen.backlog = -1

listen.allowed_clients = 127.0.0.1

listen.owner = www

listen.group = www

listen.mode = 0666

user = www

group = www

pm = dynamic


pm.max_children = 2000

pm.start_servers = 100

pm.min_spare_servers = 20

pm.max_spare_servers = 100



;access.log = /home/wwwroot/logs/phplog/$pool.access.log

access.log = /home/wwwlogs/phplog/$pool.access.log

access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"


pm.max_requests = 102400

request_terminate_timeout = 4s


request_slowlog_timeout = 2

slowlog = /home/wwwlogs/phplog/slow.log

說明:access.log這行,原來程序員配置的日誌路徑是一個共享NAS,php代碼發佈在其上,兩臺雲主機同時對它進行讀寫,擔心兩臺機器同時對同一個文件打開和寫入會帶來io上的負擔,因此把日誌寫入本地路徑/home/wwwlogs/phplog.

blob.png

通過上述修改以後,php的進程數基本處於正常,但對負載降低的作用還是很有限。查看php日誌,滾屏得飛快。


2、查看網絡狀況,算不上異常,輸出如下:

[root@web1 ~]# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

LAST_ACK 54

SYN_RECV 6

ESTABLISHED 528

FIN_WAIT1 33

TIME_WAIT 5641

修改了系統文件/etc/sysctl.conf,重新加載,效果改善不明顯。


3、流量檢查,用了兩個工具iftop和iptraf,從輸出可以判斷,基本在可接受的範圍。但有個ip地址,其一直排在流量第一位,有點可疑,是什麼業務呢?

blob.png

執行 netstat -anp|grep 172.31.176.238 進一步覈實,是對redis的請求,看起來還不少呢!

[root@web1 ~]# netstat -anp|grep 172.31.176.238|wc -l

3197

兩臺主機都查了,加起來得有7000左右的請求,不太正常吧!


3、最近借服務器挖礦很流行,擔心被***,拿acunetix一通猛掃,未見異常;又拿360認證後掃一遍(webscan.360.cn,不是windwos安裝的安全衛士一類),也一無所獲。再仔細檢查文件、系統安全日誌、帳號文件等,基本可以判斷沒有被***。


折騰了好幾天,這些招數都不靈,白天負載高都還想得通,用戶在訪問嘛。可是稀奇的是,當通過調整,負載降下去了,到凌晨的時候,又開始飆升。不得意,在nginx做訪問限制,其主要配置如下:

 map $request_method $limit {

        default         "";

        POST            $binary_remote_addr;

        }

        limit_conn_zone $binary_remote_addr zone=one_limit:10m;

        limit_req_zone $limit zone=zone_limit_post:10m rate=10r/m;

訪問量大的站點,再單獨插入如下的行:

limit_req zone=zone_limit_post burst=5;

說明:前邊一段代碼,插入到nginx主配置文件裏邊;後邊一段,插入到具體站點配置server的 location那段裏邊。如果位置不對,做語法檢查會報錯,當然也就啓動不了nginx。

重載nginx後,負載稍微有所下降,但相關部門反饋,這限制影響大用戶訪問了。


五一假期都結束了,嘗試了多種辦法,效果還是不理想。於是我就打算自己下載app,安裝在手機上,瞭解一下客戶端的訪問行爲。開打app以後,底部菜單欄三個:快訊、行情、我的。其中“快訊”又分幾個板塊--快訊、動態、微博、教程。

blob.png


通過點擊菜單和對比服務器,發現兩個問題:

1、不管點不點“行情”,客戶端都會瘋狂地去抓取行情數據。通過web訪問日誌可以看到同一個ip,對同一對象發起的頻繁請求(“POST /index.php?_url=/market/list&”)。通過與其他技術人員溝通,證實了我的猜測,客戶端每秒鐘會發起大概20次的請求,只要app開着。

blob.png


2、只要打開了app,不管是否需要,都會全部讀取所有的信息。通過“快訊”這一屏顯示內容,手指一直往上滑,一直都有內容。而我拿別人家的app做對比,別的app是上滑的過程,會有一個短暫的加載過程,即需要數據的時候,才真正去抓取和加載。


掌握這些信息後,趕緊電話跟其它人溝通,強烈建議更細app,改變現在這種無限制讀取數據的方法。相關人員也意識到問題確實由此引起,承諾儘快處理。但本文撰寫進行時,據稱目前已經強制更新了大概50%的客戶端。從服務器端看負載,趨勢逐漸好轉。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章