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