.Net高併發解決思路

高併發

高併發一直是網站上線後會遇到的一個嚴峻的考驗,渡過了一切都好,渡不過就是宕機。

在電商時代如此發達的今天,高併發無此不在雙十一 、618、雙十二,還有雷猴王的某米手機搶購。首先我們要分析高併發究竟會給我們開發者帶來什麼樣的挑戰

大量的請求,如果僅僅只有一臺服務器肯定是吃不消的,通常一些公司都是一臺服務器上部署了很多個網站也充當了數據庫服務器、redis服務器。如果要應用高併發沒有足夠的硬件支持是不行的。我們需要進行 分佈式集羣 以及 負載均衡

硬件支持有了過後,我們就需要下一步的分析

這時我們還需要提高網站的吞吐量,怎麼提高呢?首先我們需要針對IO密集型異步化操作,搶單的頁面不只是有搶單按鈕,還有商品的介紹,圖片,文字描述等。對於這些數據我們要進行緩存,一萬個用戶一萬次請求都從數據庫中取數據與只取一次剩下9999次從緩存中取效率自然是不一樣的

上面說的都是爲了解決一個 字,而併發纔是我們真正需要準備的,假如兩個用戶同時請求,這時庫存還有1,程序裏先判斷庫存是不是1,現在都符合條件,然後進行生成訂單等操作。就發生了資源共享的問題,明明只有一個訂單,但是兩個用戶都完成了訂單,那麼這個商品應該給誰呢?

併發

假設現在是一個電商網站,今天要舉辦活動,有10個商品低價銷售,但是會來搶購的人會特別多,最後只有十個人可以成功的買到商品

假設的邏輯,我們用戶進行了請求,我們把他們的信息放到庫裏,但是隻有前十個人是可以購買商品的,因爲庫存只有10個

也許我們可以用鎖來解決併發的問題,但是鎖無疑帶來的是效率的低下,用戶體驗也極低。我們想要的是快速返回,但是後面那一堆的邏輯怎麼辦呢?我們可以使用RabbitMq隊列,用戶的請求到達了搶單接口,我們只向隊列中丟一條數據後就立即返回

這時又來了一個問題,會有同一個用戶多次進行請求的情況,如果像之前的邏輯,前10條信息有二條是屬於一個人的呢,(這裏假設每個人只可以購買一次)我們就需要進行判斷了,同一個賬戶發送的多次請求,我們只認爲第一次請求是有效的,剩下的都請都直接返回。因爲是併發,我們又怎麼做到第一次請求有效呢?這時我們可以使用Redis incr存儲用戶的標識,Redis是單線程的,不存在併發的問題。incr返回爲1那麼是第一次請求,爲N則是第N請求那麼它就是無效的。這是請求標識

請求標識我們可以在搶單接口就進行判斷,也就是先拿用戶的標識去Incr,返回爲1則丟到隊列,不爲1則不丟到隊列。

也可以在rabbitmq的消費端進行處理,從rabbitmq消息隊列中拿到用戶信息後,進行incr。再進行下一步操作

丟到了消息隊列中,我們還需要去處理,consumer我們肯定是要有多個的,我們可以使用平分分發手動交付。在這裏我們把用戶的信息進行入庫,當然入庫後我們再向Redis中存入一條入庫標識

上面都是在後端,客戶端這裏點擊了搶單按鈕後可以立即導向排隊界面(是不是很熟悉,某米。。。)在這個界面進行輪詢五秒一次,判斷當前用戶在庫中的位置,如果是前十,那麼就進行訂單操作,不是。。。那就再等,看看會不會有其他用戶放棄購買資格。

測試方法:
本地模擬測試網站高訪問高併發採用的測試工具是大名鼎鼎的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

Discuz!NT是一個論壇程序,是典型的互聯網應用,在設計時本身就考慮了互聯網應用場景下高併發高訪問量的需求,在普通開源版本中,主要採用的緩存機制來提高系統的性能。

一、緩解數據庫讀取壓力

相關文章如下:
Discuz!NT 緩存設計簡析 [原創] 
http://www.cnblogs.com/daizhj/archive/2007/08/15/855163.html

這個緩存機制使用的是.Net本身提供的緩存功能,System.Web.Caching.Cache
這個方案可以解決一般訪問量不是很大的站點的需求,更高一級的,可以通過增加Web園工作進程來達到提升性能的需求,而且這個方案裏面,已經解決多進程下緩存同步的問題。

在Discuz!NT企業版中,提供了更高層次的解決方案,使用了分佈式緩存機制,引入了Memcached、Redis、LLServer,相關文章如下:

Discuz!NT中集成Memcached分佈式緩存
http://www.cnblogs.com/daizhj/archive/2009/03/23/1386652.html

在Discuz!NT中進行緩存分層(本地緩存+memcached)  
http://www.cnblogs.com/daizhj/archive/2009/11/17/1604436.html

Discuz!NT中的Redis架構設計

http://www.cnblogs.com/daizhj/archive/2011/02/21/1959511.html

Discuz!NT跨站緩存同步

http://www.cnblogs.com/daizhj/archive/2010/06/18/discuznt_memcache_syncdata.html

Discuz!NT中的LLServer架構設計

http://www.cnblogs.com/daizhj/archive/2011/08/26/discuznt_llserver_arch.html

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

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

通過以上的方案,能解決大部分高訪問高併發的需求,因爲論壇產品的特殊性,讀寫比大概是4:1,所以首先應該在讀數據方面進行減壓優化。

二、緩解Web服務器壓力

Discuz!NT在緩解Web服務器壓力上採用瞭如下的方案。

  1. 將用戶上傳的附件通過FTP方式傳送到另外一臺服務器上,相關的文章如下:Discuz!NT中遠程附件的功能實現[FTP協議]
  2. http://www.cnblogs.com/daizhj/archive/2008/07/28/1254648.html

3. 通過SQUID將靜態文件緩存分佈
使用SQUID做靜態前端,將論壇中的大部分靜態文件佈署或外鏈到一個新的HTTP鏈接上,從而給Web服務器減壓,提升性能。Discuz!NT靜態文件緩存(SQUID)解決方案
http://www.cnblogs.com/daizhj/archive/2010/06/10/1692758.html
三、負載均衡

通過以上的方案,Web服務器壓力小了,性能也提升了,但是如果遇到更高的併發訪問量,單臺Web服務器還是不能滿足需求,Discuz!NT採取了負載均衡的方案。使用了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中,數據庫作爲數據持久化工具,必定在併發訪問頻繁且負載壓力較大的情況下成爲系統性能的‘瓶頸’。即使使用上面的本地緩存等方式來解決頻繁訪問數據庫的問題,但仍舊會有大量的併發請求要訪問動態數據, 其中的‘讀寫分離’方案就是一種被廣泛採用的方案。相關文章:

    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

好了,上面就是Discuz!NT企業版爲了提升性能採取的一系列方案,確實對asp.net互聯網應用很有參考價值,其中用到的很多開源產品都是基於Linux的,如Memcached、Redis、LLServer、SQUID、NGINX、LVS、Sphinx,雖然有些產品有Windows版本,但是其性能表現能力遠遠比不上Linux上面,看來在Web應用上,性能方面的表現以及開源產品的研究,Linux遠遠的走在了Windows前面。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章