http://www.cnblogs.com/mikelij/archive/2010/11/30/1892261.htmlhtml
簡介程序員
前面一篇<<關於大型asp.net應用系統的架構-架構的選擇>>寫完以後,有一些同仁熱心回覆,有的是提問題,同時但願能舉一些例子來講明;有的是提建議,但願下一篇寫得更詳細點;還有的同仁提出不一樣的觀點。感謝你們的參與。會繼續努力的。本文將針對Layer(層)和Tier(排)的區別作個辨析。並詳細介紹3 Tier / N Tier架構中各Tier的開發。各Tier的分佈式方式。以及爲了達到高性能,低延遲,高可伸縮性,須要採起哪些方法和手段。web
關於「大型asp.net應用系統 」的概念sql
意指能支持同時在線用戶數目不少的asp.net應用系統。同時在線用戶數目要達到多少纔算大型。其實也沒有一個能夠做爲共識的定義,我的認爲若是一個應用系統能作到7x24小時同時在線用戶數很多於5000的,應該能夠稱爲大型應用系統。例如:微軟的官網www.microsoft.com,7x24小時都有來自全球的人訪問,有查閱MSDN的,有訪問微軟博客的,有看微軟產品信息的,有逛微軟論壇的,等等等等。同時訪問微軟官網的人太多了,遠多於5000。還有Myspace。 它有總數爲幾千萬的用戶,它的同時在線用戶數也是至關驚人的。它之因此能服務衆多的用戶,是因其背後有一個龐大的系統來支撐。數據庫
Layer和Tier的辨析後端
這裏針對上篇的評論,對Layer和Tier作個辨析。上篇提到了Layered(分層)的架構只能部署在同一臺服務上,有同仁在評論裏提出不一樣意見,說Layered的架構也能夠部署到多臺服務器上的。Layer是指應用程序各功能在邏輯上的分組,而Tier表示了應用程序各功能是物理分部在多臺計算機上。Layer很好理解,就是相同功能的類被邏輯上分到了一組,如:數據存取的類都放到了一塊,在同一個名稱空間下,在同一個程序集裏,商務邏輯的類也是同樣進行分組,各組之間有統一的調用形式。如商務邏輯的類引用數據存取的類,調用其方法,取得返回結果。同時UI層可調用商務邏輯層的類。商務邏輯層的類既有服務UI層的功能,也有調用數據訪問層的功能。是個承上啓下的Layer。這些Layer都是按照功能來劃分的。Layer是一種邏輯上的劃分。Tier是特指物理的劃分,應用程序的各功能,分別被放在了不一樣的服務器上,如UI功能單獨佔用一些服務器,商務邏輯功能佔用另外的一些服務器。這兩種功能部件之間有服務器的邊界,那麼就有專門負責分佈式調用的功能部件。若是單從功能邏輯上看,Tier中也是有Layer的,只是比傳統Layer的劃分多了一些用於分佈式調用的Layer。Tier是各Layer物理分離後,再加入一些負責分佈式調用的Layer才造成的。Tier和Layer是有着聯繫的。從這個意義上說,Tier是Layer物理分離時的特例。有Layer物理分離的狀況下,能夠稱之爲Layered的架構,可是實際上這並不許確,由於Tier是專門爲這個場景定義的。有物理分離,就叫Tier更準確些。Layer只要一作物理分離,就轉化成了Tier。瀏覽器
從部署角度試圖來區別Layered的架構和3 Tier / N Tier的架構。由於物理分離的場景已經被定義成Tier,那麼剩下的就只能是物理不分離的場景了。因此Layered架構就特指部署在同一臺服務上的場景(即物理不分離),3 Tier / N Tier架構就特指各Layer物理分離的場景。Layered的架構部署到多臺服務器上,理論上是能夠的,可是光靠原有的Layer是不夠的,有了服務器的邊界以後,原來在同一個進程裏面的方法調用就再也不可行,必須新加一些Layer來作分佈式的調用,才能讓原來的各Layer運行起來。等作完這一切,發現這個架構再叫Layered的架構就不合適了,必須得叫3 Tier / Tier架構才合適。緩存
Layer和Tier之間有聯繫,Layered的架構和3 Tier / N Tier架構能夠互相轉化。服務器
總體映象cookie
從前面的描述中能夠得知應用系統的每一Tier都是由許多服務器來完成的。好比UI Tier,能夠是幾十個服務器,幾百個服務器,甚至是幾千個服務器。具體每個Tier所需服務器的數目根據實際的須要來配置。所謂實際的須要就是看這一Tier服務器的硬件資源利用率。好比CPU, 內存,磁盤讀寫等狀況,若是至關高,就必須加入新的服務器部署該Tier一樣的應用到新服務器上。讓新的服務器也能分擔些壓力。其實這就是要讓應用程序能支持高可伸縮性。在每個Tier之間有硬件負載均衡,再其後就是下一個Tier的服務接口了。在其服務接口以後纔是該Tier的服務。
除了高伸縮性以外,還有如何保證高性能。即應用程序必須是良好設計的。在每個Tier的內部,能夠採起一些措施讓應用程序的執行效率達到最高。讓硬件的資源獲得充分的利用。這有一些策略,如緩存。減小訪問數據庫的次數,等等。如下是一個可伸縮的asp.net應用系統的總體映象圖:
一個在互聯網上的用戶的請求的處理過程是這樣的:
1. 首先經硬件負載均衡處理,選定一個Web服務器來響應這個請求,而後將該請求交給該服務器。
2. 此Web服務器執行所請求的頁面,該頁面的後端代碼先查詢緩存服務器,即調用緩存服務接口查詢是否已經有緩存,若是有,就直接返回緩存的結果。
3. 若是緩存裏沒有就調用商務邏輯服務接口,進而調用商務邏輯服務。商務邏輯服務執行時,若是須要訪問數據庫,會先檢查緩存中是否有緩存的數據庫內容,若是有,就會用緩存的數據庫內容來進行商務邏輯的計算。若是沒有緩存,就會調用數據訪問接口以存取數據。
4. 相似地,數據訪問服務也會查看緩存,而後根據所要求的數據內容去訪問相應的數據庫,若是是隻讀的請求,數據訪問服務能夠將數據庫訪問請求發給作日誌複製的數據庫服務器。若是是寫的請求,能夠發給主數據庫服務器。
5. 數據庫服務器執行應用的Sql請求,返回結果。再由數據服務返回給商務邏輯服務。
6. 商務邏輯服務再返回給Web服務器,由Web服務器生成頁面內容返回給互聯網上的用戶。
以上過程與Layered的架構相似,只是比Layered的架構多通過了幾個服務接口。若是沒有這些服務接口,由於UI Tier,商務邏輯Tier,數據訪問Tier是在不一樣的服務器上的,它們根本就不能直接對話。由於它們是在不一樣的.net VM中的。它們必須得藉助與這些服務接口才能互相之間進行調用。這些服務接口具體的組成技術能夠是WCF,也能夠是.net remoting,等。應該說目前最好的選擇是WCF。
UI Tier
關於SessionState的技術方案
爲了讓應用程序具備可伸縮性,必須讓每一Tier都有負載均衡的特性,也就是要作到用戶的請求由任何一個同一Tier中的服務器來處理都不會有任何問題。關於用戶Session的處理就必須有一個妥善的解決方案。有很多人不贊同採用SessionState,以爲SessionState對ASP.NET應用的性能影響比較大。還有人寫文章說同一個SessionID的AcquireRequestState會在頁面代碼前得到對Session對象的鎖,所以容易有較大的延遲,對性能影響不小。另外的人認爲Session佔用服務器的內存比較多,同時須要一些CPU資源來將Session中的對象序列化和反序列化。因此一種比較廣泛的觀點是不採用ASP.NET自己提供的Session機制。其實採用SessionState和不採用SessionState都各有特色。瞭解其特色後再作權衡取捨才比較合適。
徹底不採用SesstionState
徹底不採用SesstionState是在Web.config中寫上<sessionState mode=」Off」/> 或者 <Pages enableSessionState=」Off」/>來禁止SessionState。那整個應用的全部頁面都不會用SessionState。其實這不全面,http請求處理週期裏還有一個系統默認的httpmodule在處理SessionState。還須在Web.config加一句:
<httpModules>
<remove name="Session" />
</httpModules>
應用程序裏徹底不採用ASP.NET自己提供的SessionState機制,可是應用的需求是要求應用程序有相似於Session的機制的。好比購物車的概念。記住用戶選擇了哪些商品,在用戶點了買單時才處理用戶選擇了的商品。若是不用ASP.NET自己提供的SessionState機制,就必須本身實現一個Session機制。好比能夠在數據庫中有一張表來記錄自定義的Session數據。若是用戶瀏覽器支持cookie,能夠用該cookie存儲自定義的Session ID值。這個Session ID值用於到數據庫中去查詢存儲的Session數據。若是用戶瀏覽器不支持cookie,那麼就能夠在頁面中放置隱藏的字段(hidden field)。此隱藏字段用於存儲自定義的Session ID。還能夠用URL中參數放一個Session參數的辦法。這樣得到的Session機制是本身管理的Session機制。須要將Session的建立,過期失效,查詢Session數據,刪除舊Session等都管理起來。
這樣的自定義的Session機制將Session數據存儲到了數據庫。那麼就能夠不依賴與某一臺具體的服務器。從而得到的可伸縮的特性。
採用SessionState
採用SessionState是ASP.NET默認的機制。ASP.NET的SessionState有幾種模式。InProc,StateServer,SqlServer模式和自定義模式。InProc不支持負載均衡的場景。只有StateServer和SqlServer模式才支持。自定義模式是指咱們本身實現Session數據的持久化,好比將Session數據放到Oracle數據庫或者MySql數據庫中,自定義模式也能夠支持負載均衡。在StateServer和SqlServer模式時,放入Session中的數據都必須是能序列化的。建議採用SqlServer模式的Session機制。配置是這樣的:
<system.web>
<sessionState mode=" Off | InProc | StateServer | SQLServer "
cookieless=" true | false "
timeout=" number of minutes "
stateConnectionString=" tcpip=server:port "
sqlConnectionString=" sql connection string "
stateNetworkTimeout=" number of seconds " />
</system.web>
Session採用了SqlServer模式以後,全部數據都會經序列化,並存儲到SqlServer數據庫中。採用這種模式的Session機制,其Session能夠由任何一個UI Tier的服務器來處理,由於Session數據是存儲在專門的數據庫中的。若是是採用這種模式的Session機制,那麼最好有專門的數據庫服務器供存儲Session數據。經過上述安排,ASP.NET應用就得到了負載均衡,可伸縮的能力。
採用了ASP.NET的SessionState的以後,同一個Session ID下的不一樣頁面請求會有必定的制約。注意這裏說的同一個Session ID下的不一樣頁面。這就象數據庫的鎖機制同樣。默認的ASP頁面設置都是能對Session對象進行讀和寫。那麼若是同一個Session ID的兩個不一樣請求訪問兩個不一樣的頁面,就會由於都去鎖住Session對象,而形成有一個請求被阻塞較長時間,由於要等另外一個請求處理完畢。有同仁可能以爲奇怪,怎麼會有同一個Session ID請求兩個不一樣的頁面。其實這與頁面中的iframe,frameset和AJAX技術有關。包含iframe, frameset的頁面已經要存取Session了,iframe或者frameset裏面的頁面也要存取Session,就有可能形成一先一後,都是同一個Session ID,後面的頁面被前面的頁面鎖住,直到前面的頁面都處理完,釋放對Session的鎖,才能處理後面的頁面。AJAX也相似。也存在這個問題。這個默認的機制所帶來的延遲在小型的ASP.NET應用中能夠不用理睬。可是在大型的ASP.NET應用中是必須解決的問題。要解決這個問題,只能從應用的角度盡力減小須要寫Session的範圍,即明確肯定哪些頁面須要讀且寫Session數據。還須要肯定哪些頁面是隻須要讀Session數據。另外還須要肯定哪些頁面不須要參與讀或者寫Session數據,即與Session數據無關的頁面。經過這樣的工做,就肯定了Session的範圍。對於須要讀且寫Session的頁面,能夠顯示地在頁面中寫上< % @Page enableSessionState=」On」% >。對於只須要讀Session的頁面,能夠寫上< % @Page enableSessionState=」ReadOnly」% >。對於不須要Session的頁面,能夠寫上< % @Page enableSessionState=」Off」% >。在一個iframe相關的全部頁面中,不要全部的頁面都去讀寫Session,這樣就能夠避免Session爭鎖所帶來的延遲。AJAX所涉及的頁面也是如此,儘量地減小讀寫Session,發生這種Session爭鎖的延遲就會少一些。鎖越少,整個UI Tier的處理能力就會越大。
關於ViewState的技術方案
ViewState使服務器控件能夠在往返行程中從新填充它們的屬性值,而程序員不須要編寫任何代碼。這些屬性值包括可見的屬性,也包括不可見的。可見的屬性如Text屬性,不可見的是某些控件的ControlState。ControlState是比較特殊的內容,它老是存儲在ViewState字段中。即便用EnableViewState="false"禁止了ViewState,ViewState字段仍是有一些內容,這些內容就是ControlState。
曾經聽到很多人抱怨說ViewState大,有時光ViewState就幾百K。一個頁面的HTML,很大的部分是ViewState佔用了。微軟的文章也在說不須要ViewState的地方就禁止ViewState。因此合理決定應用程序哪些地方須要ViewState。畢竟ViewSate也必定程度上帶給程序員一些方便。禁止ViewState是能夠在整個應用的級別,頁面的級別,和控件的級別來禁止。整個應用的級別禁止ViewState: <pages enableViewState="false" enableViewStateMac="false" enableEventValidation="false"></pages>,頁面的級別如:< % @ Page EnableViewState="false" % >,控件的級別如:<asp:datagrid EnableViewState="false" datasource="..." runat="server"/>。禁止了ViewState以後,頁面中的__ViewState字段已經大大減少了,可是仍是存在。上面已經提到了,__ViewState字段裏剩下的內容就是ControlState的。若是想讓__ViewState字段沒有內容,能夠改寫Page類的此兩方法:
protected override void SavePageStateToPersistenceMedium(object viewState)
{
}
protected override object LoadPageStateFromPersistenceMedium()
{
return null;
}
這樣__ViewState字段就徹底沒有內容了。固然咱們能夠在此兩方法裏面設計出本身的持久化ViewState內容的方案。好比將ViewState持久化到緩存中去,或者持久化到SqlServer中去。那麼ViewState的內容就再也不須要發送的到用戶瀏覽器中了。上面介紹了一些在某些地方禁用ViewState的方法。下面就由開發者和用戶來決定哪些頁面或者控件須要ViewState,仍是徹底不要ViewState。ViewState機制具備兩面性,一方面方便了程序員,另外一方面可能對性能形成影響。因此要當心對待。
減小與服務器的交互次數和沒必要要的服務器端處理
Page.IsPostBack
Page.IsPostBack能夠判斷是否有Form提交。第一次訪問時的處理和有Form提交的處理是不同的。這樣能夠避免沒必要要的服務器端處理。
AutoPostBack屬性
許多服務器端控件都有AutoPostBack,能禁止的都禁止了。
多作客戶端的數據驗證
用戶在瀏覽器裏面的輸入,儘可能先用客戶端JavaScript驗證處理,等經過了再提交給服務器。這樣減小向服務器提交請求的次數。
AJAX的請求量進行控制
AJAX帶來了很炫的效果,可是能適當地減小調用AJAX調用次數,好比可否合併AJAX的調用。
用Server.Transfer不用Response.Redirect
Server.Transfer發生在服務器端,而Response.Redirect發生在用戶瀏覽器中。會多一次HTTP請求。
去除沒必要要的默認httpModule
如不要SessionState,不要WindowsAuthentication,不要PassportAuthentication等等:
<httpModules>
<remove name="Session" />
<remove name="WindowsAuthentication" />
<remove name="PassportAuthentication" />
<remove name="AnonymousIdentification" />
<remove name="UrlAuthorization" />
<remove name="FileAuthorization" />
</httpModules>
設置processModel
手動設置processModel參數中的MaxWorkerThreads 和 MaxIOThreads 屬性,經過觀察效果帶調整參數。若是機器資源容許,能夠稍微多點。
設置Web garden
只要服務器資源容許,就能夠創建Web garden,在同一個服務器上多開幾個工做者進程。32位Windows上一個進程一般只能佔用2G-3G內存(由於高地址的2G或者1G是Windows自己用來裝配系統文件用的)。64位Windows上一個進程能佔用的內存相對32位大一點,可是服務器有好比100多G的內存,能夠適當多開幾個工做者進程。這能夠增長單臺服務器的處理能力。要設置Web garden能夠先在IIS管理器裏面找到對應的應用程序池,在查看該應用程序池的高級屬性,再找到最大工做者進程參數,見圖。
緩存
ASP.NET中可用的緩存主要有:頁面級的緩存,控件級,System.Web.Caching.Cache,以及分佈式緩存如Velocity和memcahced。頁面級的緩存能夠在ASPX頁面用< % @ OutputCache Duration="10" VaryByParam="none" % >,在用戶控件中能夠用< % @ OutputCache Duration="10" VaryByParam="none" VaryByControl=」」% >,與頁面級的cache相比,多了VaryByControl參數。必須得指出這些頁面級的和控件級的緩存是存儲在特定的Web服務器上的。除非在負載均衡的硬件上作特殊的設置,不然這些頁面級和控件級的緩存都意義不大。由於這些頁面級的和控件級的緩存是存儲在特定的Web服務器上的,第一次用戶的請求是由此服務器處理的,而後有了頁面緩存,若是負載均衡硬件將第一次之後的請求交由其餘服務器處理,那麼這個處理第一次請求所作的頁面和控件級緩存都失去了意義。只有進行了特殊設置後,負載均衡的硬件才能知道剛纔這個請求是哪一個服務器處理的,就繼續向該服務器轉發HTTP請求。那麼保存的頁面等緩存纔會起到相應的做用。System.Web.Caching.Cache是個很好的緩存機制,能夠給程序員利用來緩存一些內容。惋惜它不是分佈式的。它的存儲限定在特定的服務器上。因此它對負載均衡是不支持的。要支持負載均衡,須要使用分佈式的緩存如Velocity或memcached,在UI Tier緩存的內容能夠是數據庫查詢結果。若是是本身管理的Session機制,能夠將分佈式緩存做爲Session的存儲,全部Session中的對象,能夠存儲在分佈式緩存中。還有ViewState,若是但願客戶瀏覽器不下載ViewState可是又要用ViewState,能夠重載Page類的SavePageStateToPersistenceMedium和LoadPageStateFromPersistenceMedium方法,並在此方法中將ViewState存儲到分佈式緩存。
考慮預編譯
將全部ASP.NET頁面都預先編譯。能夠減小第一次訪問時因爲ASP.NET編譯頁面所帶來的延遲。
在生產環境禁用調試模式
生產環境使用Release模式的編譯,會使程序運行稍微快一點。
儘可能避免異常
異常是非正常的程序控制流。發生異常多對性能的影響比較大。因此在程序中多對可能的狀況進行檢測,好比判斷某對象是否爲空。此一樣適用於其餘Tier。
儘可能避免鎖住資源
在多線程的場景下,儘量地去避免鎖住資源。儘可能各線程都用私有的資源。此一樣適用於其餘Tier。
壓縮頁面和相關文件
好比能夠打開IIS的gzip,還有用一個自制的HTTP module壓縮頁面的HTML, .js文件。去掉不顯示的回車和空格。進行儘量多的壓縮。
商務邏輯Tier
商務邏輯服務接口
前面已經提到,服務接口能夠考慮用WCF, Remoting等技術。目前最好的是採用WCF。緣由是WCF支持事務,支持多種通訊方式。商務邏輯服務有時是必須在互聯網上公開。因此WCF能夠選用基於Web service的通訊方式,這樣支持的外部系統比較多。若是商務邏輯服務只是在內部使用,能夠選用TCP/IP socket的通訊方式。這個商務邏輯服務接口其實就是後面的商務邏輯服務的包裝。商務邏輯服務提供哪些方法,就用相應的接口進行對應。
商務邏輯
事務的控制
商務邏輯這裏應該對事務進行控制。這與WCF接口支持事務想匹配的。
預取與緩存
好比翻頁,能夠在用戶取第一頁時,取出5頁,緩存起來,用戶日後翻幾頁時就能夠再也不查詢數據庫。減小對數據庫的查詢次數。有些查詢特別多的數據,直接都在分佈式緩存裏面存着。只有緩存裏沒有的時候,纔去查詢數據庫。
對數據庫的訪問也是能夠分佈式的調用
你們看到了上面的圖,對數據庫的訪問也是須要經過分佈式的調用才能完成。數據庫查詢的結果經過自定義的對象集合來傳遞。
採用自定義的對象做爲商務邏輯的處理對象
這些自定義的對象其實就是一個數據庫中數據的在內存中的反映。商務邏輯的處理對象最好用自定義的對象。不要用DataSet。
商務邏輯Tier最好是無狀態的
該Tier最好是狀態無關的。與商務有關的數據都存儲到分佈式緩存裏面。服務器內存裏面不長時間存儲商務有關的數據。這樣,一個對商務邏輯的請求就能夠由任何一臺商務邏輯Tier的服務器來處理,這樣就作到了負載均衡。
長時間計算型的任務最好交給其餘系統來在後臺處理
有些計算密集的任務,最好交給其餘系統在後臺運行。與計算密集的系統交互就只經過數據文件進行交互。
數據訪問Tier
數據訪問服務接口
相似於商務邏輯服務接口,數據訪問服務接口能夠考慮用WCF, Remoting等技術。目前最好的是採用WCF。緣由是WCF支持事務,支持多種通訊方式。能夠選用基於Web service的通訊方式,也能夠選用TCP/IP socket的通訊方式。這個數據訪問服務接口其實就是後面的數據訪問服務的包裝。
數據訪問
對事務的支持
如前所述,商務邏輯控制着事務,數據訪問Tier只是做爲商務邏輯控制的事務的一部分。數據訪問Tier中有許多數據庫的操做,如,查詢,更新等。建議全部的數據庫操做都用存儲過程來實現。這些數據庫操做都做爲商務邏輯控制的事務的一部分。不要在存儲過程當中實現商務邏輯。這些數據庫操做都只是替商務邏輯服務完成數據庫查詢或者存儲數據到數據庫的任務。因此不要在存儲過程或者數據訪問Tier實現任何商務邏輯的內容。
數據庫讀寫分離的支持
如前圖所示,數據庫有隻讀模式的。能夠將部分讀的請求分流到只讀模式的數據庫服務器上。只有寫的請求才流到主數據庫服務器上。這就要求分別支持不一樣的鏈接。
鏈接池的管理
每臺數據庫服務器所容許的鏈接數是必定的。須要管理好個數據訪問服務的數據庫鏈接。管理好每臺數據訪問服務服務器鏈接池。
在讀的時候用SqlDataReader
讀取數據的時候,可用SqlDataReader來讀取快速只進的數據流。
緩存
將數據庫訪問得到的內容緩存到分佈式緩存服務器上。
數據庫的設計和安排
讀寫分離
主數據庫服務器是集羣的數據庫服務器。SqlServer 2008 R2 / Windows Server 2008 最多支持16臺服務器的集羣。能夠架設一些只讀模式數據庫服務器,採用日誌複製方式,將主數據庫的全部日誌複製到只讀模式的數據庫服務器上。那麼只讀模式數據庫服務器內容就能夠保持和主數據庫服務器一致。這些只讀數據庫服務器就能夠用於分擔讀的壓力。
庫表的分離
從應用的角度將某一些數據分到多個數據庫來存儲。好比Myspace有7000多萬用戶,它把每一百萬用戶存放於一個數據庫。這樣每一個數據庫都小了不少。查詢起來相對快一些,可是程序就會設計得複雜一點。分開的數據庫能夠放在不一樣的服務器,也可在同一服務器。請根據實際狀況來決定。
表的設計
3NF, BCNF是確定要達到的。這很少說了。主要想說說彙集索引。表的彙集索引是很關鍵的一個索引。須要從應用角度考慮,最多的查詢是什麼樣的,而後按照使用最頻繁的查詢來設計彙集索引。通常來講彙集索引須要選用短的,基本數據類型的字段。好比整數, 固定長度的文本,日期之類的字段做爲彙集索引的字段。並且具備單向遞增的特性,好比日期,自增的字段。良好的彙集索引的設計,對最頻繁的查詢的性能改進是頗有幫助的,同時對插入,更新都有較大的幫助。插入時是在物理的表記錄末尾加入新記錄,引發的磁盤IO較小;更新時也可按照索引來很快查找到記錄並更新。同時也得考慮刪除時的效率。若是可能的話儘可能不要刪除記錄,只將須要刪除的記錄置成刪除狀態。
除了彙集索引,還有普通索引,合適的普通索引對查詢的性能也是有幫助的。仍是分析應用可能的查詢,能夠將次優先的那些查詢分析一下,這些查詢主要用到哪些字段做爲搜索條件。而後能夠適當地創建普通索引。這些彙集索引和普通索引對查詢的性能是有幫助的。
建立表分區
將表的記錄按必定規則來分到不一樣的數據文件上存儲。能夠分區的字段也是基本的類型。好比日期,文本等。建立分區的表的IO能夠由多個線程同時來讀寫不一樣的數據文件。在IO上能夠有所改進。
合理使用視圖
建立必定數量的試圖,能夠對查詢性能起到幫助。
分佈式調用越少越好?
前面一篇文章<<關於大型asp.net應用系統的架構-架構的選擇>>有同仁提出分佈式調用越少越好的觀點。這裏能夠說一下。若是隻有一臺服務器的時候,單純比較用分佈式調用和非分佈式調用,分佈式調用確定比非分佈式調用慢,由於分佈式調用要多一些中間接口的處理。可是非分佈式調用能同時支持那麼多人同時訪問嗎?非分佈式調用能將用戶的請求交由任何一個服務器來處理而不出現問題嗎?萬一一臺服務器出現了問題,那麼這臺服務器上的用戶就丟失他/她的會話和數據嗎?你們看吧。
固然也有這種可能,就是整個系統中某些地方採用分佈式調用,另一些地方採用非分佈式調用。例如:商務邏輯服務和數據訪問服務之間就不用分佈式調用了。那麼整個系統的圖就成了這樣:
這樣作不是不能夠,就是有其優缺點,優勢是商務邏輯調用數據訪問能夠比所有分佈式的更快,缺點就有多是,商務邏輯服務器多到必定程度,就會發現,數據庫鏈接卻不能再往上增長了,而要統一調度數據庫鏈接也是很困難的。商務邏輯與數據訪問的耦合度是否有點高?
結束語
對於大型的ASP.NET來講,首先要保證負載均衡和可伸縮性,再來作到每一臺服務器的性能最大化。要使整個系統的服務能力最大化,須要使用軟件硬件的全部手段。這裏談到的只是一些方面,不夠全面。