各們,我們用.net core 2.2+mssql 2012開發的web應用,因為專案要部署到客戶機器上,不能安裝redis,rabbitmq。應用有一個下單功能,可能會出現同時上千用戶搶單情況,請問.net core在不借助其它軟體,如何讓應用正常應對搶單場景,不會出現無回應等情況, 麻煩各位不吝賜教!謝謝!
uj5u.com熱心網友回復:
既然都要處理這樣的問題了,為啥還要糾結是不是單機。他應該是服務器如果一定認為是單機,其實也行。看你的策略
1。如果你是認為一個都不能少,每個人都必須服務,只是應對比較慢,你可以自己開記憶體佇列,記憶體快取,池,慢慢做
2。如果你認為我沒必要保證每個人,反正是搶,搶到的處理,沒搶到直接告訴他你沒搶到。這個直接放令牌桶就好。桶里有令牌,拿到令牌你就進,桶里沒令牌,直接出去。這個手段你直接參考各種所謂的 身份權限驗證攔截器就好,技術一樣,只不過人家是驗證身份,有權限進就進,沒權限進的出
uj5u.com熱心網友回復:
我找到了這個專案 https://github.com/Zhangruyun/MemoryMessageQueue,我在呼叫webapi介面時執行發布資訊:
await Task.Run(() =>
{
_queue.Publish("SalesOrderConsumer", new SalesOrderMessage(DateTime.Now.ToString()));
});
但點幾次介面,cpu就滿了,找到問題代碼是
https://github.com/Zhangruyun/MemoryMessageQueue/blob/master/MemoryQueue/MessageQueueHandler.cs
這里的 BindReceivedEvent 方法每次執行就會while回圈
while (!_queue.IsCompleted)
{
if (_queue.TryTake(out TMessage args))
_received(args, serviceFactory);
}
請問這里為什么要用while回圈,不用可以嗎?
uj5u.com熱心網友回復:
假如只能單機部署,又不能使用redis類似的kv存盤系統,還要考慮瞬間的并發。雖然有諸多限制,但也不是不能做到。思路:
使用System.Collections.Concurrent.ConcurrentBag<T>物件
偽代碼:
//假設存盤的為訂單的ID標識
var cbList = new System.Collections.Concurrent.ConcurrentBag<int>();
//把所有需要搶的訂單資料標識放入串列(事先隨機打亂放入或者順序放入皆可)
cbList.Add(1);
cbList.Add(2);
//當前cbList總數 = 2
//當用戶搶單,從佇列直接取一個回傳給客戶端
int id ;
if(!cbList.TryTake(out id)) //該方法可以保證執行緒安全,不會出現多個用戶搶到一個相同的訂單id
{
return "錯誤或者佇列已經為空";
}
//取走一個后,當前cbList總數=1
Console.WriteLine(id);//當前id為客戶搶到的訂單id標識
ConcurrentBag為多執行緒下使用的物件,可以保證執行緒安全。且單機下可以大大提高并發量
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/232265.html
標籤:ASP.NET
