asp.net解決高併發的方案

 那啥,最近見了一人叨叨叨的神侃如何處理高併發。竟然聊到服務器矩陣。我當時還沒回過神,事後細想,服務器矩陣我也知道口裏說說,可是中小企業能玩得起?做爲一個程序員不少時候只能用手頭資源來制定優化方案。(人生哲理:要警戒誇誇其談者)html

我收集了下網上提供的處理方式列在這裏。雖然我不會無聊到背下來去唬新人,但加深下映象,有個綱目仍是好的。前端

兩大點:linux

經過服務器處理高併發nginx

 調整服務器應用程序池中的最大鏈接數。程序員

1. 調整IIS 7應用程序池隊列長度web

由原來的默認1000改成65535。redis

IIS Manager > ApplicationPools > Advanced Settings數據庫

Queue Length : 65535windows

2.  調整IIS 7的appConcurrentRequestLimit設置緩存

由原來的默認5000改成100000。

appcmd.exe set config /section:serverRuntime /appConcurrentRequestLimit:100000

在%systemroot%/System32/inetsrv/config/applicationHost.config中能夠查看到該設置。

3. 調整machine.config中的processModel>requestQueueLimit的設置

由原來的默認5000改成100000。

<configuration>
<system.web>
<processModel requestQueueLimit="100000"/>

4. 修改註冊表,調整IIS 7支持的同時TCPIP鏈接數

由原來的默認5000改成100000。

reg add HKLM/System/CurrentControlSet/Services/HTTP/Parameters /v MaxConnections /t REG_DWORD /d 1000000 

完成上述4個設置,就能夠支持10萬個同時請求

參見http://www.cnblogs.com/dudu/archive/2009/11/10/1600062.html

  對於DB服務器一樣也能夠調整最大鏈接數來作優化。

      在調整優化好最大鏈接數以後,就只有軟硬件負載均衡了。硬件負載均衡可以直接經過智能交換機實現,處理能力強,並且與系統無關,可是價格貴,配置困難,不 能區分實習系統與應用的狀態。因此硬件負載均衡適用於一大堆設備,大訪問量,簡單應用。軟件負載均衡是基於系統與應用的,能過更好地根據系統與應用的情況 來分配負載。性價比高。PCL負載均衡軟件,Linux下的LVS軟件。

程序級別的併發控制:

當兩個用戶同時訪問一個頁面,一個用戶可能更新的事另外一個用戶已經刪除的記錄。或者,在一個用戶加載頁面跟他點擊刪除按鈕之間的時間裏,另外一個用戶修改了這條記錄的內容。

ADO.NET 和 Visual Studio .NET 中的併發控制

由於數據結構基於斷開的數據,因此 ADO.NET 和 Visual Studio .NET 使用開放式併發。所以,您須要添加業務邏輯,以利用開放式併發解決問題。

若是您選擇使用開放式併發,則能夠經過兩種常規的方法來肯定是否已發生更改:版本方法(實際版本號或日期時間戳)和保存全部值方法。

版本號方法

在版本號方法中,要更新的記錄必須具備一個包含日期時間戳或版本號的列。當讀取該記錄時,日期時間戳或版本號將保存在客戶端。而後,將對該值進行部分更新。

處理併發的一種方法是僅當 WHERE 子句中的值與記錄上的值匹配時才進行更新。該方法的 SQL 表示形式爲:

UPDATE Table1 SET Column1 = @newvalue1, Column2 = @newvalue2
WHERE DateTimeStamp = @origDateTimeStamp

或者,可使用版本號進行比較:

UPDATE Table1 SET Column1 = @newvalue1, Column2 = @newvalue2
WHERE RowVersion = @origRowVersionValue

若是日期時間戳或版本號匹配,則代表數據存儲區中的記錄未被更改,而且能夠安全地使用數據集中的新值對該記錄進行更新。若是不匹配,則將返回錯誤。 您能夠編寫代碼,在 Visual Studio .NET 中實現這種形式的併發檢查。您還必須編寫代碼來響應任何更新衝突。爲了確保日期時間戳或版本號的準確性,您須要在表上設置觸發器,以便在發生對行的更改 時,對日期時間戳或版本號進行更新。

保存全部值方法

使用日期時間戳或版本號的替代方法是在讀取記錄時獲取全部字段的副本。ADO.NET 中的 DataSet 對象維護每一個修改記錄的兩個版本:初始版本(最初從數據源中讀取的版本)和修改版本(表示用戶更新)。當試圖將記錄寫回數據源時,數據行中的初始值將與數 據源中的記錄進行比較。若是它們匹配,則代表數據庫記錄在被讀取後還沒有通過更改。在這種狀況下,數據集中已更改的值將成功地寫入數據庫。

對於數據適配器的四個命令(DELETE、INSERT、SELECT 和 UPDATE)來講,每一個命令都有一個參數集合。每一個命令都有用於初始值和當前值(或修改值)的參數。

注意    因爲不存在初始記錄,添加新記錄(INSERT 命令)只須要當前值;移除記錄(DELETE 命令)只須要使用初始值來定位要刪除的記錄。

如下示例顯示一個數據集命令的命令文本,該命令更新一個典型的客戶表。該命令是爲動態 SQL 和開放式併發而指定的。

UPDATE Customers SET CustomerID = @currCustomerID, CompanyName = @currCompanyName, ContactName = @currContactName,
ContactTitle = currContactTitle, Address = @currAddress, City = @currCity,
PostalCode = @currPostalCode, Phone = @currPhone, Fax = @currFax
WHERE (CustomerID = @origCustomerID) AND (Address = @origAddress OR @origAddress IS NULL AND Address IS NULL) AND (City = @origCity OR @origCity IS NULL AND City IS NULL)
AND (CompanyName = @origCompanyName OR @origCompanyName IS NULL AND CompanyName IS NULL) AND (ContactName = @origContactName OR @origContactName IS NULL AND ContactName IS NULL) AND (ContactTitle = @origContactTitle OR @origContactTitle IS NULL AND ContactTitle IS NULL)
AND (Fax = @origFax OR @origFax IS NULL AND Fax IS NULL) AND (Phone = @origPhone OR @origPhone IS NULL AND Phone IS NULL) AND (PostalCode = @origPostalCode OR @origPostalCode IS NULL AND PostalCode IS NULL);
SELECT CustomerID, CompanyName, ContactName, ContactTitle, Address, City,
PostalCode, Phone, Fax
FROM Customers WHERE (CustomerID = @currCustomerID)

請注意,九個 SET 語句參數表示將寫入數據庫的當前值,而九個 WHERE 語句參數則表示用於定位初始記錄的初始值。

前九個 SET 語句參數對應於參數集合中的前九個參數。這些參數會將其 SourceVersion 屬性設置爲 Current

接着的九個 WHERE 語句參數用於開放式併發。這些佔位符對應於參數集合中接着的九個參數,這些參數的每個都將其 SourceVersion 屬性設置爲 Original

SELECT 語句用於在發生更新後刷新數據集。它是您在「高級 SQL 生成選項」對話框中設置「刷新數據集」選項時生成的。

注意    上面的 SQL 使用命名參數,而 OleDbDataAdapter 命令則使用問號 (?) 做爲參數佔位符。

默認狀況下,若是您在「數據適配器配置嚮導」中選擇「開放式併發」選項,Visual Studio 將爲您建立這些參數。此時將由您根據本身的業務要求來添加錯誤處理代碼。ADO.NET 提供了一個 DBConcurrencyException 對象,它返回違反併發規則的行。有關更多信息,請參見處理併發錯誤

 

經過程序處理高併發

第一,緩存。

System.Web.Caching.Cache緩存  http://www.cnblogs.com/daizhj/archive/2007/08/15/855163.html

Memcached分佈式緩存 http://www.cnblogs.com/daizhj/archive/2009/03/23/1386652.html

緩存分層(本地緩存+Memcached) http://www.cnblogs.com/daizhj/archive/2009/11/17/1604436.html

Redis架構設計 http://www.cnblogs.com/daizhj/archive/2011/02/21/1959511.html

LLServer架構設計 http://www.cnblogs.com/daizhj/archive/2011/08/26/discuznt_llserver_arch.html

跨站緩存同步 http://www.cnblogs.com/daizhj/archive/2010/06/18/discuznt_memcache_syncdata.html

 

小貼士

Memcached是danga.com(運營LiveJournal的技術團隊)開發的一套分佈式內存對象緩存系統,用於在動態系統中減小數據庫負載,提高性能。具體的介紹能夠參考:

Memcached深度分析
http://www.cnblogs.com/luluping/archive/2009/01/14/1375456.html

Redis
redis是一個key-value存儲系統。和Memcached相似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操做,並且這些操做都是原子性的。在此基礎上,redis支持各類不一樣方式的排序。與memcached同樣,爲了保證效率,數據都是緩存在內存中。區別的是redis會週期性的把更新的數據寫入磁盤或者把修改操做寫入追加的記錄文件,而且在此基礎上實現了master-slave(主從)同步。

http://doc.redisfans.com/

http://www.cnblogs.com/shanyou/archive/2012/01/28/2330451.html

 

第二,靜態文件分開佈置

1.將用戶上傳的附件經過FTP方式傳送到另一臺服務器上。http://www.cnblogs.com/daizhj/archive/2008/07/28/1254648.html

2.經過SQUID將靜態文件緩存分佈
使用SQUID作靜態前端,將論壇中的大部分靜態文件佈署或外鏈到一個新的HTTP連接上,從而給Web服務器減壓,提高性能。

http://www.cnblogs.com/daizhj/archive/2010/06/10/1692758.html

 

第三,負載均衡

 

經過以上的方案,Web服務器壓力小了,性能也提高了,可是若是遇到更高的併發訪問量,單臺Web服務器仍是不能知足需求,能夠採起負載均衡的方案。

使用了LVS+KEEPALIVED、NGINX等。相關文章以下:

 

 

 

    Discuz!NT負載均衡解決方案(HA)之---LVS(Linux Virtual Server)
    http://www.cnblogs.com/daizhj/archive/2010/06/13/1693673.html

 

 

 

    Discuz!NT負載均衡解決方案(HA)之---LVS(Linux Virtual Server)

 

    http://www.cnblogs.com/daizhj/archive/2010/06/13/1693673.html

 

 

 

    Discuz!NT負載均衡方案

 

    http://www.cnblogs.com/daizhj/archive/2010/06/24/1667422.html

 

 

 

    使用的是nginx,使用nginx做爲前端負載均衡,這個確實頗有吸引力,有時間能試用下就好。

 

第四,緩解數據庫壓力

           Discuz!NT數據庫讀寫分離方案

    http://www.cnblogs.com/daizhj/archive/2010/06/21/dbsnap_master_slave_database.html

    全文搜索方案:

    Discuz!NT企業版之Sphinx全文搜索(上)

    http://www.cnblogs.com/daizhj/archive/2010/06/28/discuznt_entlib_sphinx_one.html

 

     Discuz!NT企業版之Sphinx全文搜索(下)

    http://www.cnblogs.com/daizhj/archive/2010/06/30/discuznt_entlib_sphinx_two.html

 

    處理大數據量:

    Discuz!NT千萬級數據量上的兩駕馬車--TokyoCabinet,MongoDB

    http://www.cnblogs.com/daizhj/archive/2010/07/22/1781140.html

 

 

須要掌握的知識

Memcached、Redis、LLServer、SQUID、NGINX、LVS、Sphinx

有windows版本的,也有linux版本。

 

 

 

沒有前後,程序員應該根據須要和當下條件選用。

 

 

 

本地測試高併發的工具

測試方法:
本地模擬測試網站高訪問高併發採用的測試工具是大名鼎鼎的Loadrunner,這個工具作測試的通常都知道。在代震軍的博客中,有如下幾篇介紹了經過Loadrunner進行壓力併發測試。

當DiscuzNT趕上了Loadrunner(上)
http://www.cnblogs.com/daizhj/archive/2009/09/25/1573926.html

當DiscuzNT趕上了Loadrunner(中) 
http://www.cnblogs.com/daizhj/archive/2009/09/27/1574897.html

當DiscuzNT趕上了Loadrunner(下) 
http://www.cnblogs.com/daizhj/archive/2009/09/27/1575091.html

相關文章
相關標籤/搜索