服務(wù)器高并發(fā)下的一些優(yōu)化經(jīng)驗
技術(shù)支持服務(wù)電話:15308000360 【7x24提供運(yùn)維服務(wù),解決各類系統(tǒng)/軟硬件疑難技術(shù)問題】
最近在高并發(fā)、較大數(shù)據(jù)的網(wǎng)站優(yōu)化上有一些心得和體會,所以特寫此文做一下總結(jié),這塊的高手就可以直接跳到文尾了哈,費話就不多說,直接進(jìn)正文。
1.了解你的網(wǎng)站和項目到底有多大的流量和并發(fā)?
當(dāng)項目的用戶量達(dá)到一定規(guī)模以后,網(wǎng)站往往會經(jīng)常出現(xiàn)502 bad gateway(Nginx),連接超時(Apache),MYSQL拒絕連接等問題。這個時候,一般的理解就是網(wǎng)站的訪問量比較大,請求數(shù)比較高,所以服務(wù)器不堪重負(fù),開小差去了。這個時候最快的解決辦法一般就是重啟apache,nginx或mysql,當(dāng)然這個不能解決根源,只是臨時解決一下而已。
那么,首先你應(yīng)該清楚你的網(wǎng)站的流量到底有多大?每秒的流量到底有多高?CPU占用峰值是多少?對于這個問題,首當(dāng)其沖方案的肯定使用是監(jiān)控軟件了,這類的監(jiān)控軟件比較多,有cacti(完全圖形化的流量監(jiān)控工具),zabbix(支持各種數(shù)據(jù)的監(jiān)控且可自己擴(kuò)展監(jiān)控模塊并集成報警功能,非常強(qiáng)大?。┧缘谝徊侥憔鸵欢ㄒ仍谒蟹?wù)器上安裝監(jiān)控客戶端,如cacti的snmp,zabbix的zabbix_client,然后搭建自己的監(jiān)控服務(wù)端。然后靜默收集數(shù)據(jù)一段時間,可以是幾天也可以是一周。然后了解服務(wù)器的峰值是多少,平均值是多少,CPU占用,內(nèi)存占用。這樣你能先做到對服務(wù)器的狀態(tài)心里有底。
2.查找高并發(fā)源泉
如果服務(wù)器一直運(yùn)行得比較正常,但突然一段時間經(jīng)常出現(xiàn)502,超時,超高CPU時,排除流量的超大幅度增長以外的原因,那么原因就有可能是程序卡死了或服務(wù)器硬件故障。如果排除硬件故障以后這個時候最好第一步查詢MYSQL、PHP、Nginx、Apache的錯誤日志,慢日志,定位根源文件及代碼塊,往往新功能如果沒有經(jīng)過完整的測試就上線,就非常容易引起這類的問題。
比如我們的一臺線上服務(wù)器有段時間曾經(jīng)上線了一個新功能,就是要求在某代碼模塊中將MYSQL服務(wù)器地址更改為其它機(jī)房的MYSQL服務(wù)器,由于代碼沒有經(jīng)過嚴(yán)格的測試,而直接使用了MYSQL_CONNECT重新連接。在這個功能上線以后,服務(wù)器經(jīng)常出現(xiàn)502,超時,CPU90%。后來排查時才看到這里,由于其它機(jī)房的網(wǎng)絡(luò)問題引起MYSQL_CONNECT超慢,所以大量的MYSQL_CONNECT卡死在這里引起了阻塞。另外一個統(tǒng)計模塊的file_get_contents也是同樣的問題,所以我們在后面的開發(fā)中要求一定要禁止使用file_get_contents,另外MYSQL_CONNECT也要限制超時的時間。
如果程序上沒有問題,那就要從數(shù)據(jù)庫或隊列上去查找原因了。數(shù)據(jù)庫上的問題會非常多,比如一條沒有經(jīng)常優(yōu)化的SQL語句引起表的鎖死啊,MYSQL并發(fā)量達(dá)到預(yù)設(shè)峰值,表崩潰啊,等待進(jìn)程過多啊等等。
3.使用隊列和緩存
經(jīng)驗告訴我們,隊列和緩存絕對是解決高并發(fā)的非常有效的辦法。比如郵件發(fā)送,這類功能其實客戶端并不需要等待完成,所以我們在前端只需要一直把要發(fā)送的郵件地址,內(nèi)容等一并放到隊列里,后臺程序慢慢從隊列里面去取就OK。對于隊列的解決方案有許多,比如memcache,redis等。
關(guān)于memcache,前段時間嘗試自己用memcache來寫了一個隊列,平臺windows。最終效果非常不理想,在循環(huán)的get或set時,memcache會顯得非常緩慢,并且最終的命中率一點都不高。在windows平臺上的redis會由于pull的不支持造成在高并發(fā)時經(jīng)常redis server gone away的情況。在*inux平臺上,redis表現(xiàn)了非常棒的性能和穩(wěn)定性,目前公司線上產(chǎn)品在使用redis后,已經(jīng)非常穩(wěn)定,所以redis絕對是值得使用的神器。
4.特別注意阻塞
這是一個非常嚴(yán)重的問題。HTTP上的阻塞,MYSQL的阻塞,阻塞的結(jié)果將是服務(wù)器不能正常響應(yīng)請求,CPU居高不下,并且很難發(fā)現(xiàn)問題。這要求我們在開發(fā)階段,對于容易引起阻塞的地方一定要特別注意,如果某段代碼執(zhí)行的時間會非常長,就一定要交給子進(jìn)程來做這個事情。對于這個情況,node.js是一個非常好的解決方案,因為node.js正是為非阻塞而生的。并且這幾年node.js發(fā)展迅速,各類模塊越來越多,也越來越穩(wěn)定,框架的出現(xiàn)也大大的提升了代碼編寫的速度,像express和eventproxy這類的,新手可以非??斓拈_發(fā)一個node.js未阻塞應(yīng)用。
5.數(shù)據(jù)庫的優(yōu)化
在高并發(fā)和大數(shù)據(jù)量的情況下,分表分庫是一定要的,并且盡量按模塊分。不要相信分區(qū),分區(qū)這貨非常容易引起表崩潰,特別是MYISAM引擎下,分區(qū)不僅會在一個文件夾下產(chǎn)生一堆的文件,還非常有可能因為打開的文件句柄過多而出現(xiàn)各種MYSQL錯誤。
根據(jù)情況選擇不同的引擎或數(shù)據(jù)庫軟件,MYISAM,INNODB等引擎要在不同的情況下使用,MYSIAM適用于查詢多,插入少;INNODB適用于寫入多,查詢少和事務(wù)支持。noSQL也是非常值得嘗試的產(chǎn)品,PHP對mongdb的支持還行,操作也挺方便的。
M/S在高并發(fā)下存在延遲問題,臨時解決方案是可以用緩存。
6.靜態(tài)資源與動態(tài)分離
帶寬是非常珍貴和昂貴的。有條件一定要使用CDN,在速度上提升會非常明顯,同時也能保證動態(tài)程序服務(wù)器的穩(wěn)定。
好了,以上就是近期總結(jié)的一些經(jīng)驗。