很早以前,做管理系統(tǒng),對(duì)性能體會(huì)并不是特別明顯。因?yàn)橐恍┯脩舴浅B斆?,?huì)通過調(diào)整自己的使用方式來適應(yīng)系統(tǒng)的處理能力?,F(xiàn)在想起來,有環(huán)境的原因也有能力的原因,沒有做好性能的事情,覺得有些好笑也有些遺憾?! ‖F(xiàn)在做的程序,對(duì)響應(yīng)速度、處理能力都有一定的要求,而且這些指標(biāo)直接和效益掛鉤。這個(gè)時(shí)候,性能問題就隨著系統(tǒng)的運(yùn)行不斷顯現(xiàn)出來,并在運(yùn)行過程中左右一項(xiàng)重要任務(wù)不斷改進(jìn)、調(diào)優(yōu)?! ⌒阅軆?yōu)化的過程是一種辛苦又有趣的挑戰(zhàn)?! 「倪M(jìn)總是在事關(guān)利害的時(shí)候才會(huì)有推動(dòng)力。
很多時(shí)候,自己是一個(gè)理想主義者,公司的其他一些也是,所以在系統(tǒng)設(shè)計(jì)時(shí):總試圖考慮周全,試圖具備很強(qiáng)的擴(kuò)展性,試圖一勞永逸。事實(shí)是,在沒有對(duì)業(yè)務(wù)成竹于胸、對(duì)設(shè)計(jì)沒有深刻立即的時(shí)候,很難做到。所以往往過度設(shè)計(jì)、過度開發(fā)。 多做事情,不是好事情,尤其是那些高頻度執(zhí)行的業(yè)務(wù)流程上,影響尤其嚴(yán)重。多一個(gè)環(huán)節(jié),都是意味著多消耗計(jì)算資源?! 『茉缜?,我們做的程序在結(jié)算上,要求對(duì)交易賬號(hào)三方進(jìn)行資金劃撥(一方減少,另外一方增加,第三方傭金增加),要記錄資金變動(dòng)明細(xì),要有事務(wù)保護(hù)。這業(yè)務(wù),在交易量不大的情況下,沒有問題;小幅度的性能提升也可以通過提升硬件配置來解決。但是對(duì)于我們,運(yùn)營一段時(shí)間后,性能真的很難再提升:1、業(yè)務(wù)邏輯寫得很復(fù)雜,改動(dòng)風(fēng)險(xiǎn)很大,2、所有瓶頸在數(shù)據(jù)庫上,事務(wù)經(jīng)常失敗 經(jīng)過很長時(shí)間的觀察,我們發(fā)現(xiàn)業(yè)務(wù)并沒有朝預(yù)想的方向發(fā)展,我們并不需要三方劃賬,只需要單方扣款就可以了;我們也發(fā)現(xiàn),資金做好變動(dòng)日志就可以了,事務(wù)也可以不需要。這個(gè)業(yè)務(wù)調(diào)整確定下來后,砍掉了這個(gè)模塊6成的代碼,單臺(tái)的服務(wù)性能大幅提高?! ∈潞蟾袊@,真的想多了,業(yè)務(wù)沒有想的復(fù)雜。業(yè)務(wù)上的簡化,比其他方面的優(yōu)化,我認(rèn)為更加有效,也更加樂意去做: 1. 可以刪掉很多無用的東西,維護(hù)簡單了, 2. 以前不爽的代碼終于可以丟掉了
業(yè)務(wù)總是在上升的,單臺(tái)服務(wù)器,總會(huì)有一個(gè)上限。這是常理,但在開始做程序的時(shí)候,只是想過,并有做預(yù)案。那時(shí)的想法是先完成業(yè)務(wù),再考慮性能(這個(gè)策略,仁者見仁,智者見智)。因此解決方法必定是增加硬件?! ∫黾佑布紫刃枰布?,首先要考慮系統(tǒng)自身的伸縮性問題。對(duì)之前開發(fā)的大而全的程序來說,首先要做的拆解。將業(yè)務(wù)流程拆解成多個(gè)獨(dú)立的環(huán)節(jié),每個(gè)環(huán)節(jié)自成一體,獨(dú)立運(yùn)行,環(huán)節(jié)之間通過網(wǎng)絡(luò)通訊。業(yè)務(wù)流程拆解帶來諸多好處:降低整體的復(fù)雜度,學(xué)習(xí)、開發(fā)、維護(hù)成本會(huì)大大下降?! ∠到y(tǒng)具備一定伸縮性后,就可以調(diào)整部署,我的理解是有兩個(gè)維度: 1. 不同環(huán)節(jié)部署到不同的服務(wù)器上,分?jǐn)倝毫Α ?. 關(guān)鍵環(huán)節(jié)多套部署,增加處理能力 通過部署,基本上能解決性能的問題。在這個(gè)過程中,尤其是第二個(gè)維度,數(shù)據(jù)唯一性是一個(gè)技術(shù)單點(diǎn)。
就現(xiàn)在的情況看,增加硬件的成本,還是遠(yuǎn)低于開發(fā)、維護(hù)的人力成本的,所有這個(gè)方式的性能優(yōu)化,是運(yùn)維喜歡干的。
數(shù)據(jù)庫的優(yōu)化空間,還是挺大的,主要表現(xiàn)在表索引的合理使用、表字段設(shè)計(jì)、表關(guān)聯(lián)查詢、事務(wù)?! €(gè)人認(rèn)為: ?。薄?duì)于性能要求的程序,盡量避免使用事務(wù)、和表關(guān)聯(lián)?! 。病⒑玫乃饕軌蚝艽蟪潭壬咸岣咚俣取 。场⑷绻麛?shù)據(jù)量大,要考慮表分區(qū) 一些編碼的人,對(duì)數(shù)據(jù)庫了解不多,沒有連主鍵、索引的都沒有,也時(shí)常發(fā)生。所以優(yōu)化這個(gè),是程序員,尤其懂?dāng)?shù)據(jù)庫的程序員喜歡干的事情。時(shí)常聽到一些牛人將一些耗時(shí)巨大的數(shù)據(jù)計(jì)算,瞬間提升數(shù)百、數(shù)千倍。
一般公司的程序,只是完成某一些業(yè)務(wù)而且,沒有什么大不了的技術(shù)攻關(guān),所有也談不上什么高深的技術(shù)。而我們寫的程序,經(jīng)常會(huì)因?yàn)楦鞣N各樣的原因,多做一些沒用的事情: ?。薄]有用的for循環(huán) 2、可以在一個(gè)循環(huán)里面搞定的,做了多個(gè)循環(huán) 3、一個(gè)事情反復(fù)做,通常是代碼相互調(diào)用(因?yàn)橛?jì)算結(jié)果沒有共享或傳遞) 這個(gè)事情,程序員會(huì)比較喜歡做。程序員每隔一段時(shí)間都會(huì)回頭看自己的過去,每每發(fā)現(xiàn)以前的幼稚表現(xiàn),都有沖動(dòng)去修正一下。
換一個(gè)性能高一點(diǎn)的設(shè)備。想想比較簡單,實(shí)際上也是需要有很專業(yè)的測試,才知道硬件是否真的合適。
在開發(fā)現(xiàn)在這個(gè)程序的時(shí)候,有人提醒我們IIS容易崩潰,不穩(wěn)定,性能不行?! ≡谙颠\(yùn)行之初,我們的確也是碰到這兩個(gè)問題,也懷疑IIS是否真的不行。遇到內(nèi)存消耗居高不下、線程消耗居高不下、CPU滿負(fù)荷,總是間歇性崩潰。 隨著問題的逐步解決,我們發(fā)現(xiàn),其實(shí)大部分原因是代碼編寫不當(dāng),一小部分是不了解IIS的運(yùn)行機(jī)制。目前系統(tǒng)還能夠持續(xù)穩(wěn)定運(yùn)行。
.Net有垃圾回收機(jī)制,但也不能濫用,少New一點(diǎn)也許會(huì)好點(diǎn) .Net的垃圾回收,并不是一個(gè)對(duì)象釋放了,就馬上會(huì)回收的,內(nèi)存占用高,不代表就是真的消耗了那么多
多線程是解決一些性能問題的良方,但是線程是有成本的,線程太多,CPU會(huì)把時(shí)間浪費(fèi)在線切換上 對(duì)于IO密集型的,最好采用異步的方式。同步方式意味著一個(gè)線程大部分時(shí)間消耗在等待上?! ?duì)于cpu密集性的,處理升級(jí)增加硬件投入,好像沒有辦法。 不要把ThreadPool中的線程耗光了,不然IIS就不響應(yīng)了:1、asp.net也用這個(gè)線程池;2、每秒只會(huì)創(chuàng)建2個(gè)新線程;
多數(shù)情況下,是死循環(huán)了 還有就是做了一些多余的事情
通常,在MSSQL中,有Nolock的提示符,表示允許臟讀,這種情況下,避免使用鎖,非常有效。多數(shù)情況下,我們的一些數(shù)據(jù)并沒有那么嚴(yán)格要求,即便是臟讀,也沒有什么關(guān)系。
使用Update語句,一些時(shí)候是明確只更新單行的,尤其是狀態(tài)轉(zhuǎn)換的,使用rowlock,會(huì)好一些(感覺,沒有測試確認(rèn)過)。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注