大佬們,請教個高併發下的場景問題?

時間 2021-06-03 02:03:27

1樓:涼夜

簡單點寫的話你就用阻塞佇列去實現:

使用兩個執行緒A執行緒和B執行緒,A執行緒可以當做你說的a方法作為生產者,B執行緒當做b方法,作為消費者,另外有個阻塞佇列,這個阻塞是是事件通知的關鍵;

首先A執行緒負責處理你的a方法呼叫的結果,可以將結果存入乙個map中,然後檢查map數量,數量不足則繼續結束方法,等待下乙個a呼叫,直到map達到你的條件,將map引用置空,並塞到阻塞佇列中

然後,B執行緒負責從阻塞佇列take內容,如果隊列為空,則會阻塞在take上,如果不為空,則會獲取到阻塞佇列的內容,使用b方法處理

上面這樣寫要考慮一下併發的情況,不過需求不是很複雜,併發情況不複雜

2樓:趙航

非同步,當然還要考慮下遠端承受能力和本機計算能力 ,disruptor可以控制線程數量和限流。或者mq,當然mq收集資料統一處理也可以考慮

3樓:李坤

方案跟前面幾個大佬說的差不多。如果沒有引入mq等訊息佇列,建議還是別引入新技術,因為引入新技術需要人力,技術成本,如果僅僅是該處需要mq,引入新技術會增加複雜度。修改A方法中非同步B方法為集合容器寫B,集合容器判斷達到設定的閾值後傳送資料。

使用執行緒安全容器解決併發問題即可

4樓:七転八起

這種彈性負載肯定優先考慮MQ,你方法A裡面發訊息,方法B裡面收訊息就可以了,或者是對方服務去收訊息,方法B都不用寫了。你如果非要去做批量,我認為最正確的方式應該是對方服務拿到訊息後去multi-ack。

如果必須按照你的思路去處理這一塊,我建議以事件模式來寫,內部定義乙個集合進行裝載,每次方法A進來時觸發乙個事件,往集合裡面篩然後判斷滿沒滿,滿了就執行呼叫。

這樣就不能只是乙個簡單的方法B了,而是乙個事件類。

那麼基於這種寫法就要考慮很多問題,比如服務掛了裝載的東西就丟了,放到redis裡面redis掛了(那麼redis有沒有做持久化,有沒有做主從),所以要到持久化資料庫留痕,這些都是批量帶來的需要思考的問題,因此還不如上面提到的方案。

5樓:浪狼郎

把B方法的呼叫改成定時任務,把A方法給B方法傳送的訊息放到資料庫/訊息佇列/持久話快取中。將這個過程抽象成生產者消費者模型。

B方法每次醒來,都檢查一遍目前沒傳送的資料,然後摟起來傳送出去。

有以下這些小問題要注意以下

B任務與B任務間的併發問題

B任務取資料和A任務生產任務的併發問題

B任務失敗了的話怎麼辦,是想辦法避免重複消費,還是想辦法讓方法B呼叫的遠端請求變成冪等的?

B任務多久醒來一次?這是乙個magic數字。

有些訊息佇列可以批量取資料,應該可以滿足你的需求,簡化上述問題。

高併發下怎麼做餘額扣減?

瀟湘夜雨 餘額的扣減的方式通常有以下幾類 1 基於第三方元件的分布式鎖實現 2 for update的行悲觀鎖 3 基於cas的樂觀鎖 這幾類以及效能優化前面都有說明,我補充一下第三個基於cas導致的ABA問題的解決思路 ABA問題是由CAS衍生來的,在併發極端情況下會產生,那麼什麼是ABA問題?標...

PHP高併發下的資料同步的解決方法?

陳潮進 用乙個計數器 我最近在做乙個專案高併發選課系統 每次insert之前先計數器 1然後判斷他的值是否大於max如果大於max計數器自減1 類似回滾 如果小於max 執行insert語句 ps 計數器自增和自減需要保證其原子性 推薦Redis來做計數器 max也可以用redis來存.我昨天做了乙...

請教英語大佬們乙個問題 Must the go home now

YO TALK 優途教育 不可以如果陳述句中有情態動詞 變疑問句時需要把情態動詞提前,不需要加助動詞 例如 I can run.變為疑問句是 Can I run? 行走在那年夏天 must是 情態動詞 和 實義動詞 不是乙個家族的 實義動詞最多,佔了動詞的99 所以兩種動詞用法規則不一樣。關於mus...