中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項超值服

開通VIP
【原創(chuàng)】構(gòu)建高性能ASP.NET站點(diǎn)之三 細(xì)節(jié)決定成敗

構(gòu)建高性能ASP.NET站點(diǎn)之三 細(xì)節(jié)決定成敗

 

  前言:曾經(jīng)就因為一個小小的疏忽,從而導(dǎo)致了服務(wù)器崩潰了,后來才發(fā)現(xiàn):原來就是因為一個循環(huán)而導(dǎo)致的,所以,對“注意細(xì)節(jié)“這一說法是深有感觸。

 

 

  系列文章鏈接:

  構(gòu)建高性能ASP.NET站點(diǎn) 開篇

  構(gòu)建高性能ASP.NET站點(diǎn)之一 剖析頁面的處理過程(前端)

  構(gòu)建高性能ASP.NET站點(diǎn)之二 優(yōu)化HTTP請求(前端)

  構(gòu)建高性能ASP.NET站點(diǎn)之三 細(xì)節(jié)決定成敗

  構(gòu)建高性能ASP.NET站點(diǎn) 第五章—性能調(diào)優(yōu)綜述(前篇)

  大型高性能ASP.NET系統(tǒng)架構(gòu)設(shè)計  

  構(gòu)建高性能ASP.NET站點(diǎn) 第五章—性能調(diào)優(yōu)綜述(中篇)

  構(gòu)建高性能ASP.NET站點(diǎn) 第五章—性能調(diào)優(yōu)綜述(后篇)  

  構(gòu)建高性能ASP.NET站點(diǎn) 第六章—性能瓶頸診斷與初步調(diào)優(yōu)(上篇)—識別性能瓶頸

  構(gòu)建高性能ASP.NET站點(diǎn) 第六章—性能瓶頸診斷與初步調(diào)優(yōu)(下前篇)—簡單的優(yōu)化措施

  構(gòu)建高性能ASP.NET站點(diǎn) 第六章—性能瓶頸診斷與初步調(diào)優(yōu)(下后篇)—減少不必要的請求

  構(gòu)建高性能ASP.NET站點(diǎn) 第七章 如何解決內(nèi)存的問題(前中篇)—托管資源優(yōu)化—監(jiān)測CLR性能

  構(gòu)建高性能ASP.NET站點(diǎn) 第七章 如何解決內(nèi)存的問題(前篇)—托管資源優(yōu)化—垃圾回收機(jī)制深度剖析

  構(gòu)建高性能ASP.NET站點(diǎn) 第七章 如何解決內(nèi)存的問題(前中篇)—托管資源優(yōu)化—監(jiān)測CLR性能

 

  

 

 

本篇的議題如下:

問題的描述

細(xì)節(jié)的重要性

 

  問題的描述

 

  首先,描述一下故事的背景:(希望大家耐心的故事讀完)

  在網(wǎng)站中,網(wǎng)頁中的分頁控件每次顯示10條數(shù)據(jù),每次點(diǎn)擊下一頁,就再次去取下一個10條數(shù)據(jù)。至于分頁的方法怎樣做,方法有很多,相信這點(diǎn)大家都知道。

 

  過程是這樣的:在用戶請求數(shù)據(jù)的時候(考慮到了用戶的操作和網(wǎng)站的訪問量)我會第一次取出500條數(shù)據(jù),然后把數(shù)據(jù)放在緩存中,也就是說,我取出了50頁的數(shù)據(jù),放在緩存中,這樣如果,以后用戶請求第一頁到第49頁的時候,就直接從緩存中拿數(shù)據(jù)。

  如下圖:

  

 
  第一個數(shù)據(jù)塊:

 

  采用鍵值對的形式:字典保存

 

 

  如果用戶請求到了49頁以后,那么就再次從數(shù)據(jù)庫中取出下一個數(shù)據(jù)塊(包含5011000數(shù)據(jù)),然后,現(xiàn)在內(nèi)存中就有了1000條數(shù)據(jù)。

 

  至于緩存多久,數(shù)據(jù)什么失效,失效后怎么做,這里暫不談?wù)?。(網(wǎng)站在這種緩存策略下運(yùn)行的很好)。 

  代碼如下:

 

List<Product> products=GetDataFromCacheOrDatabase(condition,pageIndex,count….);

 

 

  代碼的意思很清楚,從緩存中拿數(shù)據(jù),如果緩存中沒有對應(yīng)的數(shù)據(jù),那么就先從數(shù)據(jù)庫中拿500條數(shù)據(jù),然后放在緩存中,最后返回10條數(shù)據(jù)。

 

  后來,因為某些功能的需要,需要返回當(dāng)前頁的前6頁數(shù)據(jù)和后6頁的數(shù)據(jù),例如:如果當(dāng)前頁是第12頁,那么就要返回12頁之前6Product(也就是第6,7,8,9,10,11頁的數(shù)據(jù)),和第12頁后的頁的Product(第13,14,15,16,17,18頁的數(shù)據(jù))。 

  如下:

  

 

 

  當(dāng)然,如果當(dāng)前頁是第5頁,那么就把之前所有5頁的數(shù)據(jù)都返回,另外再加上第5頁之后的6頁數(shù)據(jù)。

 

  這里就可能涉及到跨塊獲取數(shù)據(jù),如:

  如果當(dāng)前頁是第48頁的時候,那么返回前6頁數(shù)據(jù)是沒有什么問題的,那么后6頁的數(shù)據(jù)就不足了,因為49,40也得數(shù)據(jù)可以從緩存的數(shù)據(jù)塊中取到,至于51,52,53,54頁的數(shù)據(jù),就需要再次從數(shù)據(jù)庫中讀取,然后再次緩存(如果事先沒有被緩存)。

 

 

  最后在緩存中的數(shù)據(jù)如下:

 

   

  然后調(diào)用方法:(偽碼)

 

 

List<Product> products=GetDataFromCacheOrDatabase(condition,42126….); 

 

 

  上面?zhèn)魅氲氖菑牡?/span>42頁開始的數(shù)據(jù),也就是第48頁的前6頁和后6頁的數(shù)據(jù)。

  這個方法的內(nèi)部實現(xiàn)是這樣的:

    1.    首先從第一個數(shù)據(jù)塊中取出42頁到50頁的數(shù)據(jù)

    取出數(shù)據(jù)后保存在一個List<Product> firstProductList;

    2.    從第二個數(shù)據(jù)塊中取出從51頁到54頁(如果第二個數(shù)據(jù)塊在緩存不存在,就去數(shù)據(jù)庫中取501-1000條,然后再放在緩存的第二個數(shù)據(jù)塊中)。

    保存在第二個List<Product> secondProductList

    3. 然后把兩個list合并,返回結(jié)果。例如

           secondProductList.Foreach(u=>firstProductList.Add(u));

 

  基本的實現(xiàn)就是這樣,看起來還行,也比較的合理,但是就是因為這個操作,從而導(dǎo)致服務(wù)器內(nèi)存溢出。

  大家想想看是什么原因。

 

  細(xì)節(jié)的重要性

 

  其實緩存的數(shù)據(jù)不是很多,是不足以讓服務(wù)器內(nèi)存溢出的,但是服務(wù)器還是出現(xiàn)了out of memory的異常。之前一直跑的很好,就是改了代碼之后才出現(xiàn)問題的。

 

  其實這就是由于一個最基本的錯誤產(chǎn)生的:引用類型。

  下面就來分析下:

  首先是從第一個數(shù)據(jù)塊中取出數(shù)據(jù),然后用

    List<Product> firstProductList 引用指向取出的數(shù)據(jù)

  然后從第二個數(shù)據(jù)塊中取出數(shù)據(jù),用

    List<Product> secondProductList指向數(shù)據(jù)的引用

 

  如下圖

 

 

 
  在第三步中采用

 

    secondProductList.Foreach(u=>firstProductList.Add(u));

  把secondProductList中的數(shù)據(jù)加入到firstProductList中,就因為是引用類型,其實實際操作的結(jié)果是:不斷的在改變第一個數(shù)據(jù)塊中的數(shù)據(jù),使得第一個數(shù)據(jù)塊中的數(shù)據(jù)逐漸的變多。

  現(xiàn)在當(dāng)前頁是48頁,采用上面的操作,致使第一個數(shù)據(jù)塊中的數(shù)據(jù)增加了60條,

  如果用戶再次翻頁,到了49頁,那么第一個數(shù)據(jù)塊中的數(shù)據(jù)又增多了60

  依此類推,最后導(dǎo)致了服務(wù)器內(nèi)存的不足,致使服務(wù)器崩潰了。原本的“功臣”----緩存卻成為了罪魁禍?zhǔn)住?/span>

 

  其實這個問題的解決,只要改變一點(diǎn)點(diǎn)的代碼就行了:

    List<Product> firstProductList;

    List<Product> secondProductList;

  然后

  List<Product> resultProductList=new List<Product>();然后分別把firstProductList,secondProductList遍歷,加入到resultProductList就行了。

就這么簡單。

 

  一個小的細(xì)節(jié),導(dǎo)致了大的問題。 

  

  不要忽視每一個細(xì)節(jié)。不要做沒有比較的循環(huán)等操作,一定要審視代碼,重構(gòu)代碼。 

  今天就寫到了這里,啰嗦了這么多,希望對大家有一點(diǎn)點(diǎn)的幫助。

  如有不正確,或者認(rèn)為不妥的地方,希望大家斧正!而且留下高見!謝謝!

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Asp.net程序性能優(yōu)化的七個方面
編寫高性能 Web 應(yīng)用程序的 10 個技巧
Application、Cookie、Session和Cache
C# .net用法大全
ASP.NET MVC 緩存使用示例
從MySpace的六次重構(gòu)經(jīng)歷,來認(rèn)識分布式系統(tǒng)到底該如何創(chuàng)建MySpace|技術(shù)|架構(gòu)|
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服