asp.net通過消息隊列處理高并發請求(以搶小米手機為例)_實用技巧

來源:腳本之家  責任編輯:小易  

可以通過酒店內部人員通過執法部門www.13333515.buzz防采集請勿采集本網。

網站面對高并發的情況下,除了增加硬件, 優化程序提高以響應速度外,還可以通過并行改串行的思路來解決。這種思想常見的實踐方式就是數據庫鎖和消息隊列的方式。這種方式的缺點是需要排隊,響應速度慢,優點是節省成本。

演示一下現象

創建一個在售產品表

CREATE TABLE [dbo].[product]( [id] [int] NOT NULL,--唯一主鍵 [name] [nvarchar](50) NULL,--產品名稱 [status] [int] NULL ,--0未售出 1 售出 默認為0 [username] [nvarchar](50) NULL--下單用戶 )

添加一條記錄

insert into product(id,name,status,username) values(1,'小米手機',0,null)

創建一個搶票程序

public ContentResult PlaceOrder(string userName) { using (RuanMou2020Entities db = new RuanMou2020Entities()) { var product = db.product.Where<product>(p => p.status== 0).FirstOrDefault(); if (product.status == 1) { return Content("失敗,產品已經被賣光"); } else { //模擬數據庫慢造成并發問題 Thread.Sleep(5000); product.status = 1; product.username= userName;              db.SaveChanges();               return Content("成功購買");             }       }     }

如果我們在5秒內一次訪問以下兩個地址,那么返回的結果都是成功購買且數據表中的username是lisi。

/controller/PlaceOrder?username=zhangsan

/controller/PlaceOrder?username=lisi

這就是并發帶來的問題。

第一階段,利用線程鎖簡單粗暴

Web程序是多線程的,那我們把他在容易出現并發的地方加一把鎖就可以了,如下圖處理方式。

private static object _lock = new object(); public ContentResult PlaceOrder(string userName) { using (RuanMou2020Entities db = new RuanMou2020Entities()) { lock (_lock) { var product = db.product.Where<product>(p => p.status == 0).FirstOrDefault(); if (product.status == 1) { return Content("失敗,產品已經被賣光"); } else { //模擬數據庫慢造成并發問題 Thread.Sleep(5000); product.status = 1; product.username = userName; db.SaveChanges(); return Content("成功購買"); } } } }

這樣每一個請求都是依次執行,不會出現并發問題了。

優點:解決了并發的問題。

缺點:效率太慢,用戶體驗性太差,不適合大數據量場景。

第二階段,拉消息隊列,通過生產者,消費者的模式

1,創建訂單提交入口(生產者)

public class HomeController : Controller { /// <summary> /// 接受訂單提交(生產者) /// </summary> /// <returns></returns> public ContentResult PlaceOrderQueen(string userName) { //直接將請求寫入到訂單隊列 OrderConsumer.TicketOrders.Enqueue(userName); return Content("wait"); } /// <summary> /// 查詢訂單結果 /// </summary> /// <returns></returns> public ContentResult PlaceOrderQueenResult(string userName) { var rel = OrderConsumer.OrderResults.Where(p => p.userName == userName).FirstOrDefault(); if (rel == null) { return Content("還在排隊中"); } else { return Content(rel.Result.ToString()); } }}

2,創建訂單處理者(消費者)

/// <summary> /// 訂單的處理者(消費者) /// </summary> public class OrderConsumer { /// <summary> /// 訂票的消息隊列 /// </summary> public static ConcurrentQueue<string> TicketOrders = new ConcurrentQueue<string>(); /// <summary> /// 訂單結果消息隊列 /// </summary> public static List<OrderResult> OrderResults = new List<OrderResult>(); /// <summary> /// 訂單處理 /// </summary> public static void StartTicketTask() { string userName = null; while (true) { //如果沒有訂單任務就休息1秒鐘 if (!TicketOrders.TryDequeue(out userName)) { Thread.Sleep(1000); continue; } //執行真實的業務邏輯(如插入數據庫) bool rel = new TicketHelper().PlaceOrderDataBase(userName); //將執行結果寫入結果集合 OrderResults.Add(new OrderResult() { Result = rel, userName = userName }); } } }

3,創建訂單業務的實際執行者

/// <summary> /// 訂單業務的實際處理者 /// </summary> public class TicketHelper { /// <summary> /// 實際庫存標識 /// </summary> private bool hasStock = true; /// <summary> /// 執行一個訂單到數據庫 /// </summary> /// <returns></returns> public bool PlaceOrderDataBase(string userName) { //如果沒有了庫存,則直接返回false,防止頻繁讀庫 if (!hasStock) { return hasStock; } using (RuanMou2020Entities db = new RuanMou2020Entities()) { var product = db.product.Where(p => p.status == 0).FirstOrDefault(); if (product == null) { hasStock = false; return false; } else { Thread.Sleep(10000);//模擬數據庫的效率比較慢,執行插入時間比較久 product.status = 1; product.username = userName; db.SaveChanges(); return true; } } } } /// <summary> /// 訂單處理結果實體 /// </summary> public class OrderResult { public string userName { get; set; } public bool Result { get; set; } }

4,在程序啟動前,啟動消費者線程

protected void Application_Start() { AreaRegistration.RegisterAllAreas(); GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); //在Global的Application_Start事件里單獨開啟一個消費者線程 Task.Run(OrderConsumer.StartTicketTask); }

這樣程序的運行模式是:用戶提交的需求里都會添加到消息隊列里去排隊處理,程序會依次處理該隊列里的內容(當然可以一次取出多條來進行處理,提高效率)。

優點:比上一步快了。

缺點:不夠快,而且下單后需要輪詢另外一個接口判斷是否成功。

第三階段 反轉生產者消費者的角色,把可售產品提前放到隊列里,然后讓提交的訂單來消費隊列里的內容

1,創建生產者并且在程序啟動前調用其初始化程序

public class ProductForSaleManager { /// <summary> /// 待售商品隊列 /// </summary> public static ConcurrentQueue<int> ProductsForSale = new ConcurrentQueue<int>(); /// <summary> /// 初始化待售商品隊列 /// </summary> public static void Init() { using (RuanMou2020Entities db = new RuanMou2020Entities()) { db.product.Where(p => p.status == 0).Select(p => p.id).ToList().ForEach(p => { ProductsForSale.Enqueue(p); }); } } } public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); //程序啟動前,先初始化待售產品消息隊列 ProductForSaleManager.Init(); } }

2,創建消費者

public class OrderController : Controller { /// <summary> /// 下訂單 /// </summary> /// <param name="userName">訂單提交者</param> /// <returns></returns> public async Task<ContentResult> PlaceOrder(string userName) { if (ProductForSaleManager.ProductsForSale.TryDequeue(out int pid)) { await new TicketHelper2().PlaceOrderDataBase(userName, pid); return Content($"下單成功,對應產品id為:{pid}"); } else { await Task.CompletedTask; return Content($"商品已經被搶光"); } } }

3,當然還需要一個業務的實際執行者

/// <summary> /// 訂單業務的實際處理者 /// </summary> public class TicketHelper2 { /// <summary> /// 執行復雜的訂單操作(如數據庫) /// </summary> /// <param name="userName">下單用戶</param> /// <param name="pid">產品id</param> /// <returns></returns> public async Task PlaceOrderDataBase(string userName, int pid) { using (RuanMou2020Entities db = new RuanMou2020Entities()) { var product = db.product.Where(p => p.id == pid).FirstOrDefault(); if (product != null) { product.status = 1; product.username = userName; await db.SaveChangesAsync(); } } } }

這樣我們同時訪問下面三個地址,如果數據庫里只有兩個商品的話,會有一個請求結果為:商品已經被搶光。

http://localhost:88/Order/PlaceOrder?userName=zhangsan

http://localhost:88/Order/PlaceOrder?userName=lisi

http://localhost:88/Order/PlaceOrder?userName=wangwu

這種處理方式的優點為:執行效率快,相比第二種方式不需要第二個接口來返回查詢結果。

缺點:暫時沒想到,歡迎大家補充。

說明:該方式只是個人猜想,并非實際項目經驗,大家只能作為參考,慎重用于項目。歡迎大家批評指正。

到此這篇關于asp.net通過消息隊列處理高并發請求(以搶小米手機為例)的文章就介紹到這了,更多相關asp.net 消息隊列處理高并發 內容請搜索真格學網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持真格學網!

゛?破゛?解゛?密゛?碼゛?查゛?詢゛?記゛?錄゛?這゛?個゛?可゛?以゛?向゛?他゛?了゛?解゛.゛?他?゛? ゛??゛:▄4 8?4 6 9?8 6?9 1.▄゛?技 ゛?數゛? 好 ゛ ? 訫゛ ?譽゛ ?高゛ ゛找 ?゛他?゛ 放 ?゛心?゛好處是:清熱去火,防止感冒。將橘子皮切成絲晾干作枕芯用,有順氣、降壓的功效,對高血壓病人很適用。舒適,有助于更快入睡.枕頭不宜過高,、放個橘子在旁邊,可以幫助深度睡眠,以清火,明目,鎮靜,安神,淡淡的桔香味更讓人心曠神怡。指導意見:用晾干后的橘子皮做成橘皮枕對于治療高血壓病、失眠等,制作時還可加入銀花、菊花、玫瑰花、燈芯草等。希望對您有所幫助。1、巧防暈車 在上車前1小時,用新鮮的橘子皮,向內折成雙層,對準鼻孔,用手指擠提捏橘子皮,皮中就會噴射出無數股細小的橘香油霧并被吸入鼻孔。在上車后繼續隨時擠壓吸入,可有效地預防暈車。2、巧治凍瘡 將橘皮用火烤焦,研成粉末,再用植物油調均勻,抹在患處。3、巧治慢性支氣管炎 橘皮5至15克,泡水當茶飲,常用。4、巧治咳嗽 用干橘皮5克,加水2杯煎湯后,放少量姜末、紅糖趁熱服用:也可取鮮橘皮適量,切碎后用開水沖泡,加入白糖代茶飲,有化痰止咳之功效。5、巧治便秘 鮮橘皮12克或干橘皮6克,煎湯服用,可治便秘。6、巧解酒 用鮮橘皮30克,加鹽少許煎湯飲服,醒酒效果頗佳。7、巧治睡覺磨牙 睡覺前10分鐘,口中含一塊橘皮,然后入睡,最好不要將橘皮吐出,若感到不適時,再吐出。8、巧防止牙齒“酸倒”食酸橘對老人或牙齒過敏者均不宜。其實,只要在食酸橘后,即用剩下的新鮮橘皮泡開水喝下,就可以防止牙齒“酸倒”。9、巧治乳腺炎 生橘皮30克、甘草6克,煎湯飲服,可治乳腺炎。10、巧治口臭 將一小塊橘皮含在口中,或嚼一小塊鮮橘皮,可治口臭。11、巧解魚蟹之毒 用適量的橘子皮煎湯飲服,可緩解食魚、食蟹后的中毒。12、巧治胃寒嘔吐 將橘皮和生姜片加水同煎,飲其湯,可治療胃寒、嘔吐。13、巧理氣消脹 用鮮橘子皮泡開水,加適量白糖,為橘皮茶,飲后可理氣消脹,生津潤喉。14、巧治消化不良 將50克橘皮浸泡在酒里。這種酒有溫補脾胃的功效,用于消化不良、反胃嘔吐等癥,對多食油膩而引起的消化不良、不思飲食癥,尤為有效。15、巧清肺化痰 將橘子皮洗凈后置于白酒中,浸泡20余天即可飲用,其味醇厚爽口,且有清肺化痰的作用。若浸泡的時間再長一點,至春節或開春后再飲,則味道更佳。16、巧治風寒感冒 鮮橘皮、生姜片,加紅糖適量煎水喝,可治療風寒、感冒、嘔吐、咳嗽。17、巧提神開胃 將橘皮洗凈切成絲后曬干,與茶葉放在一起存放,飲用時,用開水沖服,其味清香可口,有開胃、通氣、提神的功效。18、巧治胰腺炎 用橘子皮30克、甘草10克和水共煎當茶飲。有助于治療急性胰腺炎。19、巧降血壓 將橘子皮切成絲晾干作枕芯用,有順氣、降壓的功效,對高血壓病人很適用。20、巧治腳沙蟲 腳趾間被污水雜漬,易發生奇癢,若搔抓,則破皮流水,臭味難聞,此時可用鮮橘子皮猛擦癢處,止癢效果甚佳。植物激素是植物體內合成的對植物生長發育有顯著作用的幾類微量有機物質。也被成為植物天然激素或植物內源激素。植物激素有五類,即生長素(Auxin)、赤霉素(GA)、細胞分裂素(CTK)、脫落酸(ABA)和乙烯(ethyne,ETH)。它們都是些簡單的小分子有機化合物,但它們的生理效應卻非常復雜、多樣。例如從影響細胞的分裂、伸長、分化到影響植物發芽、生根、開花、結實、性別的決定、休眠和脫落等。所以,植物激素對植物的生長發育有重要的調節控制作用。植物激素的化學結構已為人所知,有的已可以人工合成,如吲哚乙酸;有的還不能人工合成,如赤霉素。目前市場上售出的赤霉素試劑是從赤霉菌的培養過濾物中制取的。這些外加于植物的吲哚乙酸和赤霉素,與植物體自身產生的吲哚乙酸和赤霉素在來源上有所不同,所以作為植物生長調節劑,也有稱為外源植物激素。最近新確認的植物激素有,茉莉酸(酯)等等植物體內產生的植物激素有赤霉素、激動素、脫落酸等。現已能人工合成某些類似植物激素作用的物質如2,4-D(2,4-二氯苯酚代乙酚)等。植物自身產生的、運往其他部位后能調節植物生長發育的微量有機物質。人工合成的具有植物激素活性的物質稱為生長調節劑。已知的植物激素主要有以下 5類:生長素、赤霉素、細胞分裂素、脫落酸和乙烯。生長素 C.D.達爾文在1880年研究植物向性運動時,只有各種激素的協調配合,發現植物幼嫩的尖端受單側光照射后產生的一種影響,能傳到莖的伸長區引起彎曲。1928年荷蘭F.W.溫特從燕麥胚芽鞘尖端分離出一種具生理活性的物質,稱為生長素,它正是引起胚芽鞘伸長的物質。1934年荷蘭F.克格爾等從人尿得到生長素的結晶,經鑒定為吲哚乙酸。促進>橡膠樹漆樹等排出乳汁。在植物中,則吲哚乙酸通過酶促反應從色氨酸合成。十字花科植物中合成吲哚乙酸的前體為吲哚乙腈,西葫蘆中有相當多的吲哚乙醇,也可轉變為吲哚乙酸。已合成的生長素又可被植物體內的酶或外界的光所分解,因而處于不斷的合成與分解之中。生長素在低等和高等植物中普遍存在。并使細胞膜的透性增加,在高等植物體內,乙烯可以促進RNA和蛋白質的合成,生長素主要集中在幼嫩、正生長的部位,如禾谷類的胚芽鞘,它的產生具有“自促作用”,雙子葉植物的莖頂端、幼葉、花粉和子房以及正在生長的果實、種子等;衰老器官中含量極少。用胚芽鞘切段證明植物體內的生長素通常只能從植物的上端向下端運輸,而不能相反。這種運輸方式稱為極性運輸,能以遠快于擴散的速度進行。但從外部施用的生長素類藥劑的運輸方向則隨施用部位和濃度而定,如根部吸收的生長素可隨蒸騰流上升到地上幼嫩部位。低濃度的生長素有促進器官伸長的作用。從而可減少蒸騰失水。超過最適濃度時由于會導致乙烯產生,生長的促進作用下降,甚至反會轉為抑制。不同器官對生長素的反應不同,根最敏感,芽次之,莖的敏感性最差。種子中較高的脫落酸含量是種子休眠的主要原因。生長素能促進細胞伸長的主要原因,在于它能使細胞壁環境酸化、水解酶的活性增加,從而使細胞壁的結構松弛、可塑性增加,有利于細胞體積增大。因此是一種生長抑制劑,生長素還能促進 RNA和蛋白質的合成,促進細胞的分裂與分化。它的作用在于抑制 RNA和蛋白質的合成,對于維持頂端優勢、促進果實發育,通常在衰老的器官或組織中的含量比在幼嫩部分中的多。生長素也有重要作用。脫落酸存在于植物的葉、休眠芽、成熟種子中。吲哚乙酸可以人工合成。生產上使用的是人工合成的類似生長素的物質如吲哚丙酸、吲哚丁酸、萘乙酸、2,4-滴、4-碘苯氧乙酸等,可用于防止脫落、促進單性結實、疏花疏果、插條生根、防止馬鈴薯發芽等方面。愈傷組織容易生芽;反之容易生根。2,在組織培養中當它們的含量大于生長素時,4-滴曾被用做選擇性除草劑。細胞分裂素還可促進芽的分化。赤霉素 1926年日本黑澤在水稻惡苗病的研究中,發現感病稻苗的徒長和黃化現象與赤霉菌(Gibberellafujikuroi)有關。1938年藪田和住木從赤霉菌的分泌物中分離出了有生理活性的物質,定名為赤霉素(GA)。從50年代開始,英、美的科學工作者對赤霉素進行了研究,現已從赤霉菌和高等植物中分離出60多種赤霉素,分別被命名為GA1,GA2等。以后從植物中發現有十多種細胞分裂素,赤霉素廣泛存在于菌類、藻類、蕨類、裸子植物及被子植物中。商品生產的赤霉素是GA3、GA4和GA7。GA3又稱赤霉酸,是最早分離、鑒定出來的赤霉素,分子式為C19H22O6。即6-呋喃氨基嘌呤。高等植物中的赤霉素主要存在于幼根、幼葉、幼嫩種子和果實等部位,由甲羥戊酸經貝殼杉烯等中間物合成。后證明其中含有一種能誘導細胞分裂的成分,赤霉素在植物體內運輸時無極性,通常由木質部向上運輸,由韌皮部向下或雙向運輸。赤霉素最顯著的效應是促進植物莖伸長。無合成赤霉素的遺傳基因的矮生品種,用赤霉素處理可以明顯地引起莖稈伸長。目前在啤酒工業上多用赤霉素促進a-淀粉酶的產生,赤霉素也促進禾本科植物葉的伸長。在蔬菜生產上,常用赤霉素來提高莖葉用蔬菜的產量。一些需低溫和長日照才能開花的二年生植物,干種子吸水后,用赤霉素處理可以代替低溫作用,使之在第1年開花。赤霉素還可促進果實發育和單性結實,打破塊莖和種子的休眠,促進發芽。干種子吸水后,胚中產生的赤霉素能誘導糊粉層內a-淀粉酶的合成和其他水解酶活性的增加,常用赤霉素來提高莖葉用蔬菜的產量。促使淀粉水解,在蔬菜生產上,加速種子發芽。赤霉素也促進禾本科植物葉的伸長。目前在啤酒工業上多用赤霉素促進a-淀粉酶的產生,避免大麥種子由于發芽而造成的大量有機物消耗,從而節約成本。細胞分裂素 這種物質的發現是從激動素的發現開始的。由韌皮部向下或雙向運輸。1955年美國人F.斯庫格等在煙草髓部組織培養中偶然發現培養基中加入從變質鯡魚精子提取的DNA,可促進煙草愈傷組織強烈生長。后證明其中含有一種能誘導細胞分裂的成分,稱為激動素,高等植物中的赤霉素主要存在于幼根、幼葉、幼嫩種子和果實等部位,即6-呋喃氨基嘌呤。它在植物中并不存在。但后來發現植物中存在其他具有促進細胞分裂作用的物質,GA3又稱赤霉酸,總稱為細胞分裂素。第一個天然細胞分裂素是1964年D.S.萊瑟姆等從未成熟的玉米種子中分離出來的玉米素。以后從植物中發現有十多種細胞分裂素,GA2等。都是腺嘌呤的衍生物。高等植物細胞分裂素存在于植物的根、葉、種子、果實等部位。根尖合成的細胞分裂素可向上運到莖葉,但在未成熟的果實、種子中也有細胞分裂素形成。細胞分裂素的主要生理作用是促進細胞分裂和防止葉子衰老。定名為赤霉素(GA)。綠色植物葉子衰老變黃是由于其中的蛋白質和葉綠素分解;而細胞分裂素可維持蛋白質的合成,從而使葉片保持綠色,發現感病稻苗的徒長和黃化現象與赤霉菌(Gibberellafujikuroi)有關。延長其壽命。細胞分裂素還可促進芽的分化。在組織培養中當它們的含量大于生長素時,愈傷組織容易生芽;反之容易生根。可用于防止脫落、促進單性結實、疏花疏果、插條..內容來自www.13333515.buzz請勿采集。


  • 本文相關:
  • .net core如何在網絡高并發下提高json的處理效率詳解
  • asp.net(c#)實現功能強大的時間日期處理類完整實例
  • asp.net中datatable導出到excel的方法介紹
  • asp.net對txt文件相關操作(讀取、寫入、保存)
  • c#設置本地網絡如dns、網關、子網掩碼、ip等等
  • 如何解決asp.net負載均衡時session共享的問題
  • asp.net中listbox 綁定多個選項為選中及刪除實現方法
  • 淺析asp.net萬能json解析器
  • asp.net傳多個值到其它頁面的具體實現
  • asp.net在mvc中maxlength特性設置無效的解決方法
  • 詳解asp.net core 之 identity 入門(二)
  • 無需對方同意定位
  • 別人的酒店住宿記錄怎樣查詢
  • 想監聽別人的手機通話記錄怎么辦
  • 網站首頁網頁制作腳本下載服務器操作系統網站運營平面設計媒體動畫電腦基礎硬件教程網絡安全基礎應用實用技巧自學過程首頁asp.net實用技巧.net core如何在網絡高并發下提高json的處理效率詳解asp.net(c#)實現功能強大的時間日期處理類完整實例asp.net中datatable導出到excel的方法介紹asp.net對txt文件相關操作(讀取、寫入、保存)c#設置本地網絡如dns、網關、子網掩碼、ip等等如何解決asp.net負載均衡時session共享的問題asp.net中listbox 綁定多個選項為選中及刪除實現方法淺析asp.net萬能json解析器asp.net傳多個值到其它頁面的具體實現asp.net在mvc中maxlength特性設置無效的解決方法詳解asp.net core 之 identity 入門(二)java正則表達式 pattern和matche未將對象引用設置到對象的實例 (asp.net(c#)網頁跳轉七種方法小結未能加載文件或程序集“xxx”或它asp.net“服務器應用程序不可用”asp.net中的幾種彈出框提示基本實asp.net gridview 72般絕技asp.net生成excel并導出下載五種asp.net漢字轉拼音和獲取漢字首字asp.net對路徑"xxxxx"asp.net 頁面編碼常見問題小結sqlserver 批量數據替換助手v1.0版發布.netcore利用blockingcollection實現簡易用asp.net做的個性化的郵件發送系統asp.net性能優化之讓瀏覽器緩存動態網頁的asp.net中實體類對象賦值到表單的實現代碼asp.net cookie清除的代碼net操作access數據庫示例分享iis部署asp.net mvc網站的方法asp.net 獲取treeview中第一個選中的節點
    免責聲明 - 關于我們 - 聯系我們 - 廣告聯系 - 友情鏈接 - 幫助中心 - 頻道導航
    Copyright © 2017 www.13333515.buzz All Rights Reserved
    3排列五开奖结果