掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
隨著.NET應(yīng)用范圍越來越廣泛,對(duì)于大多數(shù)應(yīng)用程序所有者和開發(fā)人員來說,確保.NET應(yīng)用程序的優(yōu)良性能是最重要的需求。

.NET應(yīng)用程序運(yùn)行緩慢的原因可能有很多。這些包括不正確的內(nèi)存大小調(diào)整,GC暫停,代碼級(jí)錯(cuò)誤,異常的過多日志記錄,同步塊的高使用率,IIS服務(wù)器瓶頸等等。
在此博客中,我們將研究.NET應(yīng)用程序中的一些常見性能問題,并提供解決和解決這些問題的技巧。
.NET異常不是一件壞事,只有錯(cuò)誤的用法卻是壞事。這就是大多數(shù)開發(fā)人員所相信的,如果對(duì)異常進(jìn)行了適當(dāng)?shù)奶幚恚磼伋?,捕獲和處理(并且不忽略),則會(huì)帶來穩(wěn)定的性能。
然而,就像太多的廚師會(huì)寵壞了湯一般,太多未處理的異常會(huì)導(dǎo)致代碼效率低下并影響應(yīng)用程序性能[1]。
尤其是隱藏的異常更糟,這種隱藏異常就像雷區(qū),一旦未能檢查這些異常,它們會(huì)影響網(wǎng)頁加載時(shí)間。
.NET的另一個(gè)問題是過多地記錄了異常。日志記錄可能是您的調(diào)試工具庫中的一個(gè)好工具,它可以識(shí)別在處理應(yīng)用程序時(shí)記錄的異常。
但是,當(dāng)設(shè)置日志記錄來捕獲應(yīng)用程序體系結(jié)構(gòu)每一層的異常時(shí),最終可能會(huì)在Web,服務(wù)和數(shù)據(jù)層上記錄相同的異常。這可能會(huì)增加應(yīng)用程序代碼的負(fù)擔(dān),并增加響應(yīng)時(shí)間。在生產(chǎn)環(huán)境中,只需要記錄致命事件和錯(cuò)誤就需要小心。
記錄所有信息,包括參考消息,調(diào)試和警告,很容易使您的生產(chǎn)日志文件file臃腫,進(jìn)而影響代碼處理。
有用的疑難解答提示:
.NET Framework提供了許多線程同步選項(xiàng),例如進(jìn)程間互斥,讀取器/寫入器鎖等。
有時(shí),.NET開發(fā)人員將以這樣的方式編寫代碼:在給定的條件下,只有一個(gè)線程可以得到服務(wù)。
時(shí)間以及其他要處理的并行線程將不得不在隊(duì)列中等待。例如,結(jié)帳應(yīng)用程序根據(jù)其業(yè)務(wù)邏輯應(yīng)一次處理一個(gè)請(qǐng)求。同步和鎖定有助于序列化傳入線程以執(zhí)行。通過創(chuàng)建同步的代碼塊并在特定對(duì)象上施加鎖定,需要傳入線程等待直到同步對(duì)象上的鎖可用為止。盡管此策略在某些情況下會(huì)有所幫助,但不應(yīng)過度使用。
有用的疑難解答提示:
有時(shí)特定的URL緩慢時(shí),這是一回事。但是,當(dāng)IIS網(wǎng)站剛剛掛起并且所有或大多數(shù)網(wǎng)頁需要永久加載時(shí),它不會(huì)變得更糟。通常,當(dāng)應(yīng)用程序過載或死鎖時(shí),可能會(huì)掛起。.NET應(yīng)用程序通常會(huì)遇到兩種類型的應(yīng)用程序掛起方案。
硬掛(IIS問題):這通常發(fā)生在請(qǐng)求處理管道的開始–在請(qǐng)求排隊(duì)的地方。由于應(yīng)用程序死鎖,所有可用線程都可能被阻塞,導(dǎo)致隨后的傳入請(qǐng)求最終在等待服務(wù)的隊(duì)列中結(jié)束。當(dāng)活動(dòng)請(qǐng)求數(shù)超過IIS服務(wù)器上配置的并發(fā)限制時(shí),也會(huì)發(fā)生這種情況。此類掛起將表現(xiàn)為請(qǐng)求超時(shí)并收到503 Service Unavailable錯(cuò)誤。硬性影響所有URL和整個(gè)Web應(yīng)用程序本身。
軟掛(ASP.NET問題):這通常是由于特定段中的應(yīng)用程序代碼錯(cuò)誤而造成的,僅影響幾個(gè)URL而不影響整個(gè)網(wǎng)站。通常,由ASP.NET控制器或頁面引起的掛起發(fā)生在
階段。為了確認(rèn)這一點(diǎn),您可能想調(diào)試一下調(diào)試器,以確切了解請(qǐng)求被卡在哪里。檢查模塊名稱,階段名稱和URL。URL將指示導(dǎo)致掛起的控制器/頁面。
當(dāng)托管堆上分配的對(duì)象使用的內(nèi)存超過應(yīng)用程序開發(fā)人員配置的可接受閾值時(shí),.NET CLR中的垃圾回收(GC)會(huì)初始化。這是GC.Collect方法跳轉(zhuǎn)到動(dòng)作并回收死對(duì)象占用的內(nèi)存的時(shí)候。CLR中的GC通常發(fā)生在存儲(chǔ)短期對(duì)象的第0代堆中。當(dāng)GC發(fā)生在包含長(zhǎng)期對(duì)象的第二代堆中時(shí),它稱為Full GC。每次發(fā)生GC都會(huì)在CLR上增加大量CPU負(fù)載,并減慢應(yīng)用程序的處理速度。因此,如果GC暫停時(shí)間更長(zhǎng)且更頻繁,則應(yīng)用程序?qū)②呌诜啪彙?/p>
Microsoft IIS Server是.NET Framework的關(guān)鍵部分。IIS是Web服務(wù)器,它承載構(gòu)建于.NET上的Web應(yīng)用程序或網(wǎng)站,并運(yùn)行W3WP進(jìn)程,該進(jìn)程負(fù)責(zé)響應(yīng)傳入的請(qǐng)求。IIS還集成了公共語言運(yùn)行時(shí)(CLR),該運(yùn)行時(shí)負(fù)責(zé)為線程處理分配資源。由于IIS具有各種活動(dòng)部分,因此IIS中的瓶頸可能會(huì)對(duì).NET應(yīng)用程序性能產(chǎn)生直接的負(fù)面影響。
常見的IIS服務(wù)器問題:
并非總是會(huì)影響應(yīng)用程序性能的.NET代碼問題。運(yùn)行緩慢的查詢通常是常見的原因。但是通常是.NET應(yīng)用程序開發(fā)人員因應(yīng)用程序性能下降[6]而受到指責(zé)。
這樣做的原因是,SQL性能如何影響.NET應(yīng)用程序處理沒有上下文可見性。ADO.NET和ODP.NET連接問題可能是查詢處理緩慢的原因之一,但常見原因是查詢的格式不正確。執(zhí)行計(jì)劃不正確,索引缺失,架構(gòu)設(shè)計(jì)不當(dāng),緩沖池較小,聯(lián)接缺失,緩存不正確,連接未正確進(jìn)行池化等也是導(dǎo)致數(shù)據(jù)庫查詢處理受到影響的原因。
雖然DBA負(fù)責(zé)數(shù)據(jù)庫性能和查詢創(chuàng)建,但.NET應(yīng)用程序所有者需要在應(yīng)用程序處理期間跟蹤查詢級(jí)別的問題。這將有助于區(qū)分代碼級(jí)問題和數(shù)據(jù)庫問題,并且.NET開發(fā)人員不必花時(shí)間尋找代碼中的問題。
溫馨提示:除了數(shù)據(jù)庫調(diào)用速度慢之外,由于外部調(diào)用[8](例如HTTP,Web Service,WCF)也可能導(dǎo)致速度慢[9]。
.NET Framework不是獨(dú)立的層。使用.NET Framework的應(yīng)用程序?qū)⑴c基礎(chǔ)架構(gòu)(例如任何虛擬服務(wù)器,容器或云基礎(chǔ)架構(gòu))有很多依賴性。然后,可能會(huì)有后端存儲(chǔ)設(shè)備。盡管這些不是直接的.NET問題,但是這些基礎(chǔ)結(jié)構(gòu)組件中的任何一個(gè)問題都可能同樣影響.NET性能。
就像我們看到IIS服務(wù)器和數(shù)據(jù)庫可能遇到瓶頸一樣,VM可能會(huì)耗盡資源,SAN陣列可能會(huì)遇到無法處理的高IOPS,或者如果.NET應(yīng)用程序托管在Azure上,那么可能會(huì)有一個(gè)應(yīng)用程序服務(wù)運(yùn)行不正常。
在大多數(shù)應(yīng)用程序環(huán)境中,與網(wǎng)絡(luò)相關(guān)的投訴都位居榜首。無論是網(wǎng)絡(luò)問題還是應(yīng)用程序問題之間總是存在責(zé)備游戲。網(wǎng)絡(luò)擁塞,丟包或設(shè)備故障可能會(huì)影響應(yīng)用程序的性能和連接性。
.NET應(yīng)用程序環(huán)境的總體性能保證要求應(yīng)用程序與支持基礎(chǔ)結(jié)構(gòu)之間的依存關(guān)系具有相關(guān)的可見性。確保實(shí)施融合的應(yīng)用程序和基礎(chǔ)結(jié)構(gòu)監(jiān)視策略以捕獲基礎(chǔ)結(jié)構(gòu)問題。
當(dāng)您專注于捕獲和解決所有這些問題時(shí),請(qǐng)務(wù)必記住,編寫干凈而高效的代碼可以解決.NET方面的許多問題。編寫良好的代碼,保持系統(tǒng)和基礎(chǔ)架構(gòu)的健康,并實(shí)施必要的工具以監(jiān)控自動(dòng)化。這將幫助您提供高性能的.NET應(yīng)用程序和數(shù)字體驗(yàn)。
[1] 應(yīng)用程序性能: https://www.eginnovations.com/blog/what-is-application-performance-monitoring/
[2] 代碼分析工具: https://www.eginnovations.com/microsoft-net-monitoring
[3] 事務(wù)跟蹤工具: https://www.eginnovations.com/microsoft-net-monitoring
[4] 監(jiān)視IIS性能: https://www.eginnovations.com/iis-monitoring
[5] 所有方面,: https://www.eginnovations.com/iis-monitoring
[6] 應(yīng)用程序性能下降: https://www.eginnovations.com/webinar/my-application-is-slow-troubleshooting-prevention/
[7] 數(shù)據(jù)庫監(jiān)視工具: https://www.eginnovations.com/database-monitoring
[8] 速度慢之外,由于外部調(diào)用: https://www.eginnovations.com/microsoft-net-monitoring#supported
[9] 速度慢: https://www.eginnovations.com/microsoft-net-monitoring#supported

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流