成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

聊聊ASP.Net服務性能優化原則

開發 后端
服務器性能問題,通常在數據少的時候不會顯現,也無需太多關注。但一旦數據量大了,就會變成一個麻煩且必須處理的事。

[[400327]]

本文轉載自微信公眾號「老王Plus」,作者老王Plus的老王。轉載本文請聯系老王Plus公眾號。

服務器性能問題,通常在數據少的時候不會顯現,也無需太多關注。但一旦數據量大了,就會變成一個麻煩且必須處理的事。

通常,性能問題可能有許多不同的原因。內存問題、緩慢的數據庫請求和太少的機器只是其中的一部分。手上的項目,每天10億級的數量量,在最近一個時間段,填了很多坑,也學到了不少東西。

今天這個文章,我會把這一段的體會,總結成幾大類問題。當然,分類不一定很嚴謹,重要的是能給到大家一些建議,真到用時,能少刨一些坑,就夠了。另外,次序也不重要,我是想到哪些到哪的,并不是說前邊的內容就比后面的內容更需要注意。

1. 數據庫調用

數據庫調用的性能,會嚴重影響系統整體的性能。大多數情況下,與數據庫快速交互是獲得良好性能的最重要的因素。

以下幾個點需要重點關注:

  • 索引策略

索引對數據庫交互的影響不需要解釋。重要的是檢查,檢查每一個索引,和每一個查詢語句。很多時候,你以為的未必是你以為的。檢查查詢語句和條件對索引的使用,檢查索引的結構。要確保每個查詢語句,能正確使用你所希望使用的索引。

  • 表結構設計

表結構設計最重要的,是對業務的理解。對數據之間的關系理解越深,表結構越趨于合理。

  • 同樣的工作,盡可能在數據庫上完成,避免在服務器中完成

這個話不太好理解,用代碼舉個例子:

  1. // 好的方式 
  2. var girls = dbContext.Users.Where(user => user.gender == female); 
  3. var count = girls.Count(); 
  4.  
  5. // 不好的方式 
  6. var girls = dbContext.Users.Where(user => user.gender == female).ToList(); 
  7. var count = girls.Count

下邊這種方式,第一行以ToList()結束。當實體執行查詢時,會從數據庫中檢索并獲取全部數據,然后在服務器中進行計數。而上面的方式,會在數據庫中直接計數。很顯而易見的,數據庫中執行計數,網絡傳輸的代價會更少。

  • 盡可能讓數據庫離應用服務器"近"點

數據庫到應用服務器之間,無非是網絡。更"近"的網絡,會帶來更少的延時。這個"近"說的是網絡拓撲上的近,不是位置和距離。對于多機房分布式的應用,起碼的要求是讓一個或幾個完整的副本集與應用服務處于同一個數據中心。

  • 用數據庫希望的方式使用數據庫

數據庫有很多種,關系型、NoSQL、內存數據庫,等等。并不是所有的數據庫都一樣。有些適合Key-Value鍵值對,有些適合事務處理,有些適合存儲日志。

在開發中,不要拘泥于數據庫類型,而應該根據業務類型和數據庫特性進行使用。比方說,MongoDB,本身是基于文檔的數據庫,結構上很不適合JOIN操作。但它非常適合存儲包含大量業務數據的文檔。所以,使用時要避免使用JOIN操作的業務。當然,這只是個例子。事實上MongoDB對于類似JOIN的內容,有更好的處理模式,這個大家可以自行了解。

  • 保證數據庫有足夠的硬件資源

服務器的伸縮一般提的比較高,但其實數據庫的伸縮性也需要非常重視。數據庫服務器,要關注到存儲空間、內存、網絡和CPU。經驗中,接近極限時,服務器未必會有明確的警報給你;而等到有警報出現時,恐怕已經到達極限并發生了故障,就非常難于處理了。

所以,當發現某些任務開始變慢,就意味著需要全面檢查了。

  • 承認某些低效查詢的存在

不是所有的查詢都可以做到高效。尤其查詢是基于某些實體框架,例如EF或Hibernate。在技術和時間可能的情況下,少用數據框架是個好習慣。

  • 使用連接池,而不是單個連接

如果每個查詢都需要重新建立連接,那是非常可怕的,從性能到應用的可靠性。使用數據庫,第一件事就是學會如何使用連接池。

  • 小心使用存儲過程

當有需要花費大量時間的復雜查詢需要處理時,存儲過程是個解決方案。但一定要小心,一定要小心,一定要小心,重要的事情說三遍。

在我的團隊中,存儲過程是被禁止使用的。相對來說,這兒安全的要求超過性能。

不過,在這個文章中,尤其在討論數據庫操作的性能時,咱還是不能忘了存儲過程。

  • 數據庫分片策略

分布式數據庫性能的核心在于分片。分片就一個原則:讓業務的每一個查詢操作,對應盡可能少的分片。

上面寫的,其實是一些原則。實際上,最難的部分是確定這些問題。所以,需要對各種工具都熟悉。通常,數據庫本身也能提供相關內容,例如慢查詢、擴展問題、網絡瓶頸等。對于數據庫,不要僅限于使用,一定深度的了解會對成長有相當的幫助。

2. 內存壓力

對于某些高吞吐量的應用,服務器的內存壓力是最常見的問題。

當吞吐量非常大的時候,垃圾回收(GC)會跟不上內存的分配和釋放。而且這種壓力的體現,是服務器在垃圾回收上花費的時間更多,而執行代碼的時間更少。

這種狀態在多種情況下都可能發生。最常見的情況是內存容量耗盡。當您達到內存極限時,垃圾回收器將出現恐慌,并啟動更頻繁的整體垃圾回收,而這種模式的回收代價非常大。但問題是,為什么會發生這種情況?為什么你內存使用接近極限了?原因通常是錯誤或不太好的緩存管理或內存泄漏。通過捕獲內存快照并檢查是什么占用了所有字節,可以很容易地用內存分析器發現這一點。

重要的是首先要意識到你有內存問題。最簡單的方法是使用性能計數器。

3. 緩存數據

緩存可以是一個非常好、非常有效的優化技術。典型的例子是,當客戶端發送請求時,服務器可以將結果保存在緩存中。當客戶端再次發送相同的請求(不一定是同一個客戶端)時,服務器不需要再次查詢數據庫或進行任何計算來獲得結果,而只是從緩存中獲取它。

考慮一下搜索引擎的做法。如果這是一個常見的搜索,它可能會被要求每天多次。如果不做緩存,每次都使用計算力去生成相同的頁面,是不是很可怕?

當然,使用緩存,在一定程序上增加了應用的復雜性。首先,每隔一段時間就需要使緩存失效并刷新,對吧?我們總不可能永遠返回相同的結果。另一個問題是,如果使用不合理,緩存容易膨脹,并導致內存問題。

好在,ASP.Net有很多已經實現的優秀的緩存庫可以幫助解決大部分的工作。

4. 垃圾回收優化

應用服務器性能優化中,垃圾回收是一個必須考慮的問題。

我們知道,Dotnet垃圾回收有兩種不同的模式:工作站模式和服務器模式。前者被優化為以最小的資源使用快速響應,而后者用于高吞吐量。

Dotnet運行時默認將桌面應用程序中的GC模式設置為工作站模式,而服務器中的GC模式設置為服務器模式。這個默認值幾乎總是最好的。在服務器中,GC將使用更多的機器資源,但是能夠處理更大的吞吐量。換句話說,該進程將有更多的線程專門用于垃圾回收,它將能夠每秒釋放更多字節。

相比由系統自動默認GC模式而言,手動設置應用的垃圾回收模式會是一個安全的做法。服務器并不是總能正確地意識到需要什么樣的回收模式。

5. 減少不必要的客戶端請求

客戶端請求的數量,很大程度上可以決定服務器的數量或服務器的負載。所以,通過一些技巧來減少服務器請求,也是優化的一部分內容。

這個內容需要在應用中具體探討或體會。我只舉幾個實用的例子:

  • 自動完成機制

通常這種應用,就是我們在前端輸入時,客戶端從第一個輸入字符開始做API調用。比方我們輸入"Dotnet",那我們會向服務器發送6個請求 --- "D"、"Do"、"Dot"、"Dotn"等等。但實際上,考慮到輸入的連續性,我們可以在調用前,做個短時的延時,比方停止輸入500ms后才向服務器發送請求。你可能不會相信,我們實際應用中實測的結果,可以減少93%的調用。

  • 客戶端緩存

還是上面的例子。對于同一個應用,很多位置的輸入都是相同或類似的。如果我們將自動完成的結果緩存在客戶端,而不是每次都發送這些請求,同樣可以減少很多不必要的請求。

  • 批處理

應用中,一個頁面跟服務器的交互通常會有很多。通常最無腦的做法,就是一個事件發送一個請求。這樣的方式無形中會對服務器產生相當的壓力。如果可能,把這樣的事件合并成一個請求,會更有效率,對服務器更友好。

6. 正確處理掛起的請求

客戶端對服務器的請求,可能會被掛起。也就是說,客戶端發送了一個請求,但未收到響應,或者準確地說,是經過一個比較長的時間后,收到一個超時響應。雖然我們不希望發生這樣的事,但這種事情總在發生:處理請求時間過長、或代碼死鎖、或代碼出錯并且沒有正常捕獲錯誤,當然還包括等待一些本應該出現但實際未出現的東西,例如來自隊列的消息、長時間的數據庫響應或對另一個服務的調用。

本質上,當一個請求被掛起時,會掛起一個或多個線程。但應用程序并不會停,并繼續處理新的請求。如果這個掛起在其它請求上也有重現,那隨著時間,掛起的線程將越來越多,并最終影響服務器或系統的響應。

因此,請求掛起對服務器性能的影響非常大。

這個問題的解決,需要針對核心的部分,就是掛起的部分進行調試,以確保程序處理了各種可能性,并不會產生任何意外的掛起。

7. 服務器崩潰

服務器崩潰也是一個可能的性能問題。

通常來說,客戶端請求期間發生一般的異常時,應用程序不會崩潰。但總有一些問題,比方上下文之外的異常,或者一些災難性的異常,比方OutOfMemoryException、ExecutionEngineException、StackOverflowException,當這些發生時,不管加多少catch,也擋不住崩潰的發生。

通常如果的托管在Web Server上,例如:IIS、Nginx、Jexus上的ASP.Net應用,崩潰時Web Server會自動回收資源,并重啟應用。客戶端的感覺是臨時的慢響應或503錯誤。

而如果是直接啟動的ASP.Net應用,則程序會永久關閉,需要手動重啟。這將是一個問題。

所以,一方面,使用Web Server會是一個好習慣。另一方面,還是要檢查代碼,從根本上解決問題。

8. 永遠記著應用規模

這個問題說起來很簡單,但實際開發中,其實經常會忘記,或者說忽略應用的規模。

用緩存,會忘了分布式緩存,忘了同步問題,直接使用單機內存緩存;

數據庫寫入,會忘了并發下的數據一致性問題;

。。。太多了,不一一寫了

解決的辦法,是從頭開始,就把代碼規模化 --- 從開發到測試,全部使用雙向擴展,即水平擴展(向外擴展)和垂直擴展(向上擴展)。垂直擴展意味著服務機器添加更多的功能,比如更多的CPU和RAM,而水平擴展意味著添加更多的機器。

記著,從開發和測試開始,就要使用與生產環境使用同等規模的環境來做。

9. 同步和異步

應用服務不同于桌面應用或終端應用。當服務在執行過程中需要等待響應時,比方數據庫操作、或者調用別的服務時,這個服務本身就開始有了一定的風險。如果數據庫或別的服務正忙著處理別的請求、或者存在性能問題時,必然會把性能問題傳遞到調用方。

怎么辦?

解決的基本模式是異步調用。異步調用有兩個含義:

  • 代碼的異步調用,就是我們常說的async和await。
  • 架構的異步調用。這個通常是通過使用Kafka或RabbitMQ這樣的隊列服務來完成。向隊列發送消息,并不等待響應。由另一個服務提取這些消息并處理。這個方式,通常是不需要回復的服務。而如果需要回復,也可以用類似SignalR這樣的推送通知。

重要的是,這樣的方式下,系統組件不需要主動等待服務。一切都是異步處理的。服務之間的耦合可以松散很多。

當然同樣的,這樣會讓代碼變得更復雜。

取舍之間,是對代碼的控制力。

10. 一個小總結

出差期間,斷斷續續寫的這個東西,似乎有點亂,但就這樣吧,:P

在實際項目中,很多方面稍不注意,就能搞亂服務器的性能,而且有很多地方會出錯。而解決呢,又沒有捷徑和技巧,需要仔細的計劃,有經驗的工程師,以及大量的緩沖時間來應對可能出現的問題。

后面我寫寫一些工具的應用吧。很多方面,還是有好的工具可以幫助解決或至少是快速發現問題的。

 

總之,這是一篇個人的經驗之談,希望能給大家一個拋磚引玉的作用。

 

責任編輯:武曉燕 來源: 老王Plus
相關推薦

2024-06-11 09:00:00

異步編程代碼

2009-08-13 16:22:18

ASP.NET性能優化

2012-05-16 10:24:26

ASP.NET性能優化

2009-08-13 15:49:18

ASP.NET性能優化

2011-10-19 09:41:15

ASP.NET性能優化

2011-07-06 08:46:30

2011-06-28 15:14:10

ASP.NET性能優化

2018-02-23 13:55:16

ASP.NET性能優化技巧

2011-10-17 09:54:18

ASP.NET性能

2024-12-05 08:14:41

2023-03-08 18:43:50

GPU模型隔離

2011-07-19 10:46:49

Windows 7優化

2012-12-24 09:55:15

JavaJava WebJava優化

2009-07-21 14:16:02

ASP.NET管道優化

2009-08-04 17:16:16

ASP.NET代碼優化

2011-10-14 10:37:54

ASP.NET

2021-02-19 06:54:33

配置系統ASP.NET Cor

2010-01-08 09:43:23

SQL Server分Analysis Se

2012-12-24 09:23:27

ASP.NETC#IIS

2011-02-13 09:37:55

ASP.NET
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人欧美一区二区 | 欧美2区 | 青青草中文字幕 | 久久国产成人 | 国产91在线 | 亚洲 | 欧美在线看片 | 日韩在线看片 | 无码一区二区三区视频 | 亚洲一区视频在线 | 亚洲精品99久久久久久 | 日韩精品 电影一区 亚洲 | 精品一区二区三区四区外站 | 久久成人免费 | 欧美成人一区二区 | 网站黄色在线 | 91看片在线观看 | 免费视频一区二区 | 日韩免费 | 免费a国产 | 精品视频免费 | 你懂的av | 国产精品区二区三区日本 | 一区二区三区回区在观看免费视频 | 91综合网 | 日韩精品在线一区二区 | 免费午夜剧场 | 国产精品久久久久久婷婷天堂 | 久久久久1 | 操久久| 亚洲在线 | 日韩精品影院 | 亚洲成人一区二区三区 | 亚洲一区视频在线 | 亚洲最大av网站 | 日本在线免费视频 | 一区二区三区四区在线 | 国产精品一区二区在线观看 | 一区二区三区不卡视频 | 日韩欧美一区二区三区四区 | www4虎 | 每日更新av |