.Net高并发解决思路(转)
.Net高并發(fā)解決思路
2018年10月21日 14:19:14?趙東小生?閱讀數(shù):736高并發(fā)
高并發(fā)一直是網(wǎng)站上線后會遇到的一個嚴(yán)峻的考驗,渡過了一切都好,渡不過就是宕機(jī)。
在電商時代如此發(fā)達(dá)的今天,高并發(fā)無此不在雙十一 、618、雙十二,還有雷猴王的某米手機(jī)搶購。首先我們要分析高并發(fā)究竟會給我們開發(fā)者帶來什么樣的挑戰(zhàn)
大量的請求,如果僅僅只有一臺服務(wù)器肯定是吃不消的,通常一些公司都是一臺服務(wù)器上部署了很多個網(wǎng)站也充當(dāng)了數(shù)據(jù)庫服務(wù)器、redis服務(wù)器。如果要應(yīng)用高并發(fā)沒有足夠的硬件支持是不行的。我們需要進(jìn)行?分布式集群?以及?負(fù)載均衡
硬件支持有了過后,我們就需要下一步的分析
這時我們還需要提高網(wǎng)站的吞吐量,怎么提高呢?首先我們需要針對IO密集型做異步化操作,搶單的頁面不只是有搶單按鈕,還有商品的介紹,圖片,文字描述等。對于這些數(shù)據(jù)我們要進(jìn)行緩存,一萬個用戶一萬次請求都從數(shù)據(jù)庫中取數(shù)據(jù)與只取一次剩下9999次從緩存中取效率自然是不一樣的
上面說的都是為了解決一個?高?字,而并發(fā)才是我們真正需要準(zhǔn)備的,假如兩個用戶同時請求,這時庫存還有1,程序里先判斷庫存是不是1,現(xiàn)在都符合條件,然后進(jìn)行生成訂單等操作。就發(fā)生了資源共享的問題,明明只有一個訂單,但是兩個用戶都完成了訂單,那么這個商品應(yīng)該給誰呢?
并發(fā)
假設(shè)現(xiàn)在是一個電商網(wǎng)站,今天要舉辦活動,有10個商品低價銷售,但是會來搶購的人會特別多,最后只有十個人可以成功的買到商品
假設(shè)的邏輯,我們用戶進(jìn)行了請求,我們把他們的信息放到庫里,但是只有前十個人是可以購買商品的,因為庫存只有10個
也許我們可以用鎖來解決并發(fā)的問題,但是鎖無疑帶來的是效率的低下,用戶體驗也極低。我們想要的是快速返回,但是后面那一堆的邏輯怎么辦呢?我們可以使用RabbitMq隊列,用戶的請求到達(dá)了搶單接口,我們只向隊列中丟一條數(shù)據(jù)后就立即返回
這時又來了一個問題,會有同一個用戶多次進(jìn)行請求的情況,如果像之前的邏輯,前10條信息有二條是屬于一個人的呢,(這里假設(shè)每個人只可以購買一次)我們就需要進(jìn)行判斷了,同一個賬戶發(fā)送的多次請求,我們只認(rèn)為第一次請求是有效的,剩下的都請都直接返回。因為是并發(fā),我們又怎么做到第一次請求有效呢?這時我們可以使用Redis?incr存儲用戶的標(biāo)識,Redis是單線程的,不存在并發(fā)的問題。incr返回為1那么是第一次請求,為N則是第N請求那么它就是無效的。這是請求標(biāo)識
請求標(biāo)識我們可以在搶單接口就進(jìn)行判斷,也就是先拿用戶的標(biāo)識去Incr,返回為1則丟到隊列,不為1則不丟到隊列。
也可以在rabbitmq的消費(fèi)端進(jìn)行處理,從rabbitmq消息隊列中拿到用戶信息后,進(jìn)行incr。再進(jìn)行下一步操作
丟到了消息隊列中,我們還需要去處理,consumer我們肯定是要有多個的,我們可以使用平分分發(fā)與手動交付。在這里我們把用戶的信息進(jìn)行入庫,當(dāng)然入庫后我們再向Redis中存入一條入庫標(biāo)識
上面都是在后端,客戶端這里點擊了搶單按鈕后可以立即導(dǎo)向排隊界面(是不是很熟悉,某米。。。)在這個界面進(jìn)行輪詢五秒一次,判斷當(dāng)前用戶在庫中的位置,如果是前十,那么就進(jìn)行訂單操作,不是。。。那就再等,看看會不會有其他用戶放棄購買資格。
測試方法:
本地模擬測試網(wǎng)站高訪問高并發(fā)采用的測試工具是大名鼎鼎的Loadrunner,這個工具做測試的一般都知道。在代震軍的博客中,有以下幾篇介紹了通過Loadrunner進(jìn)行壓力并發(fā)測試。
當(dāng)DiscuzNT遇上了Loadrunner(上)
http://www.cnblogs.com/daizhj/archive/2009/09/25/1573926.html
當(dāng)DiscuzNT遇上了Loadrunner(中)?
http://www.cnblogs.com/daizhj/archive/2009/09/27/1574897.html
當(dāng)DiscuzNT遇上了Loadrunner(下)?
http://www.cnblogs.com/daizhj/archive/2009/09/27/1575091.html
Discuz!NT是一個論壇程序,是典型的互聯(lián)網(wǎng)應(yīng)用,在設(shè)計時本身就考慮了互聯(lián)網(wǎng)應(yīng)用場景下高并發(fā)高訪問量的需求,在普通開源版本中,主要采用的緩存機(jī)制來提高系統(tǒng)的性能。
一、緩解數(shù)據(jù)庫讀取壓力
相關(guān)文章如下:
Discuz!NT 緩存設(shè)計簡析 [原創(chuàng)]?
http://www.cnblogs.com/daizhj/archive/2007/08/15/855163.html
這個緩存機(jī)制使用的是.Net本身提供的緩存功能,System.Web.Caching.Cache
這個方案可以解決一般訪問量不是很大的站點的需求,更高一級的,可以通過增加Web園工作進(jìn)程來達(dá)到提升性能的需求,而且這個方案里面,已經(jīng)解決多進(jìn)程下緩存同步的問題。
在Discuz!NT企業(yè)版中,提供了更高層次的解決方案,使用了分布式緩存機(jī)制,引入了Memcached、Redis、LLServer,相關(guān)文章如下:
Discuz!NT中集成Memcached分布式緩存
http://www.cnblogs.com/daizhj/archive/2009/03/23/1386652.html
在Discuz!NT中進(jìn)行緩存分層(本地緩存+memcached)??
http://www.cnblogs.com/daizhj/archive/2009/11/17/1604436.html
Discuz!NT中的Redis架構(gòu)設(shè)計
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架構(gòu)設(shè)計
http://www.cnblogs.com/daizhj/archive/2011/08/26/discuznt_llserver_arch.html
Memcached是danga.com(運(yùn)營LiveJournal的技術(shù)團(tuán)隊)開發(fā)的一套分布式內(nèi)存對象緩存系統(tǒng),用于在動態(tài)系統(tǒng)中減少數(shù)據(jù)庫負(fù)載,提升性能。具體的介紹可以參考:
Memcached深度分析
http://www.cnblogs.com/luluping/archive/2009/01/14/1375456.html
通過以上的方案,能解決大部分高訪問高并發(fā)的需求,因為論壇產(chǎn)品的特殊性,讀寫比大概是4:1,所以首先應(yīng)該在讀數(shù)據(jù)方面進(jìn)行減壓優(yōu)化。
二、緩解Web服務(wù)器壓力
Discuz!NT在緩解Web服務(wù)器壓力上采用了如下的方案。
3.?通過SQUID將靜態(tài)文件緩存分布
使用SQUID做靜態(tài)前端,將論壇中的大部分靜態(tài)文件布署或外鏈到一個新的HTTP鏈接上,從而給Web服務(wù)器減壓,提升性能。Discuz!NT靜態(tài)文件緩存(SQUID)解決方案
http://www.cnblogs.com/daizhj/archive/2010/06/10/1692758.html
三、負(fù)載均衡
通過以上的方案,Web服務(wù)器壓力小了,性能也提升了,但是如果遇到更高的并發(fā)訪問量,單臺Web服務(wù)器還是不能滿足需求,Discuz!NT采取了負(fù)載均衡的方案。使用了LVS+KEEPALIVED、NGINX等。相關(guān)文章如下:
Discuz!NT負(fù)載均衡解決方案(HA)之---LVS(Linux Virtual Server)
http://www.cnblogs.com/daizhj/archive/2010/06/13/1693673.html
Discuz!NT負(fù)載均衡解決方案(HA)之---LVS(Linux Virtual Server)
http://www.cnblogs.com/daizhj/archive/2010/06/13/1693673.html
Discuz!NT負(fù)載均衡方案
http://www.cnblogs.com/daizhj/archive/2010/06/24/1667422.html
使用的是nginx,使用nginx作為前端負(fù)載均衡,這個確實很有吸引力,有時間能試用下就好。
四、緩解數(shù)據(jù)庫壓力
在Discuz!NT中,數(shù)據(jù)庫作為數(shù)據(jù)持久化工具,必定在并發(fā)訪問頻繁且負(fù)載壓力較大的情況下成為系統(tǒng)性能的‘瓶頸’。即使使用上面的本地緩存等方式來解決頻繁訪問數(shù)據(jù)庫的問題,但仍舊會有大量的并發(fā)請求要訪問動態(tài)數(shù)據(jù),?其中的‘讀寫分離’方案就是一種被廣泛采用的方案。相關(guān)文章:
Discuz!NT數(shù)據(jù)庫讀寫分離方案
http://www.cnblogs.com/daizhj/archive/2010/06/21/dbsnap_master_slave_database.html
全文搜索方案:
Discuz!NT企業(yè)版之Sphinx全文搜索(上)
http://www.cnblogs.com/daizhj/archive/2010/06/28/discuznt_entlib_sphinx_one.html
? Discuz!NT企業(yè)版之Sphinx全文搜索(下)
http://www.cnblogs.com/daizhj/archive/2010/06/30/discuznt_entlib_sphinx_two.html
處理大數(shù)據(jù)量:
Discuz!NT千萬級數(shù)據(jù)量上的兩駕馬車--TokyoCabinet,MongoDB
http://www.cnblogs.com/daizhj/archive/2010/07/22/1781140.html
好了,上面就是Discuz!NT企業(yè)版為了提升性能采取的一系列方案,確實對asp.net互聯(lián)網(wǎng)應(yīng)用很有參考價值,其中用到的很多開源產(chǎn)品都是基于Linux的,如Memcached、Redis、LLServer、SQUID、NGINX、LVS、Sphinx,雖然有些產(chǎn)品有Windows版本,但是其性能表現(xiàn)能力遠(yuǎn)遠(yuǎn)比不上Linux上面,看來在Web應(yīng)用上,性能方面的表現(xiàn)以及開源產(chǎn)品的研究,Linux遠(yuǎn)遠(yuǎn)的走在了Windows前面。
轉(zhuǎn)載于:https://www.cnblogs.com/LiZhongZhongY/p/10954517.html
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的.Net高并发解决思路(转)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 这样写的,一定是辣鸡代码!
- 下一篇: 构建可读性更高的 ASP.NET Cor