打趴系统的不一定是技术
五一節就這么廢了,因為線上服務器負載一直飆高。
負載這么高,居然還能登錄系統進行操作,佩服佩服。
這是一套新上線的業務,購買的是阿里云的主機及服務。業務請求先到負載均衡,業務承載由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.
通過上述修改以后,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地址,其一直排在流量第一位,有點可疑,是什么業務呢?
執行 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以后,底部菜單欄三個:快訊、行情、我的。其中“快訊”又分幾個板塊--快訊、動態、微博、教程。
通過點擊菜單和對比服務器,發現兩個問題:
1、不管點不點“行情”,客戶端都會瘋狂地去抓取行情數據。通過web訪問日志可以看到同一個ip,對同一對象發起的頻繁請求(“POST /index.php?_url=/market/list&”)。通過與其他技術人員溝通,證實了我的猜測,客戶端每秒鐘會發起大概20次的請求,只要app開著。
2、只要打開了app,不管是否需要,都會全部讀取所有的信息。通過“快訊”這一屏顯示內容,手指一直往上滑,一直都有內容。而我拿別人家的app做對比,別的app是上滑的過程,會有一個短暫的加載過程,即需要數據的時候,才真正去抓取和加載。
掌握這些信息后,趕緊電話跟其它人溝通,強烈建議更細app,改變現在這種無限制讀取數據的方法。相關人員也意識到問題確實由此引起,承諾盡快處理。但本文撰寫進行時,據稱目前已經強制更新了大概50%的客戶端。從服務器端看負載,趨勢逐漸好轉。
總結
以上是生活随笔為你收集整理的打趴系统的不一定是技术的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python中global 和 nonl
- 下一篇: EF Code First Migrat