1. 程式人生 > 其它 >java面經-訊息佇列-阻塞與非阻塞-同步與非同步

java面經-訊息佇列-阻塞與非阻塞-同步與非同步

一、“阻塞”與“阻塞”與“同步”與“非同步”

1、同步與非同步

同步與非同步關注的是訊息通訊機制(synchronous communication/ asynchronous communication)

所謂同步,就是在發出一個‘呼叫’時,在沒有得到結果之前,該‘呼叫’就不返回。但是一旦呼叫返回,就得到了返回值。換句話說就是由'呼叫者'主動等待這個結果

所謂非同步,就在呼叫發出以後,這個呼叫就直接返回了,所以沒有結果。換句話說,當一個非同步過程呼叫發出後,呼叫者不會立刻得到結果。而是在‘呼叫’發出後,被呼叫者通過狀態通知呼叫者,或者回調函式處理這個呼叫

 

例子1:

你打電話問書店老闆有沒有《
分散式系統
》這本書,如果是同步通訊機制,書店老闆會說,你稍等,”我查一下",然後開始查啊查,等查好了(可能是5秒,也可能是一天)告訴你結果(返回結果)。
而非同步通訊機制,書店老闆直接告訴你我查一下啊,查好了打電話給你,然後直接掛電話了(不返回結果)。然後查好了,他會主動打電話給你。在這裡老闆通過“回電”這種方式來回調。

2、阻塞與非阻塞

阻塞和非阻塞關注的是等待呼叫結果(訊息,返回值)的狀態

阻塞呼叫是指呼叫結果返回之前,該執行緒會被掛起。呼叫執行緒只有在得到結果才會返回。

非阻塞呼叫不能立刻得到結果之前,該呼叫不會阻塞當前執行緒。

 

總結:阻塞與非阻塞著重於等待呼叫結果的狀態(是否阻塞當前執行緒),同步與非同步主要著重於等待結果。

 

例子2:

你打電話問書店老闆有沒有《分散式系統》這本書,你如果是阻塞式呼叫,你會一直把自己“掛起”,直到得到這本書有沒有的結果,如果是非阻塞式呼叫,你不管老闆有沒有告訴你,你自己先一邊去玩了, 當然你也要偶爾過幾分鐘check一下老闆有沒有返回結果。
在這裡阻塞與非阻塞與是否同步非同步無關。跟老闆通過什麼方式回答你結果無關。

使用訊息佇列的好處: 1、將使用者的請求資料儲存到訊息佇列之後(生成),就立即返回結果。隨後系統再對訊息佇列進行消費。(提高使用者體驗) 因為使用者請求資料寫入訊息隊列了就立即返回給使用者了,但是請求資料在後續的業務校驗、寫資料庫等操作中可能會失敗。因此,使用訊息佇列進行非同步處理之後,需要適當修改業務流程進行配合
。 比如使用者提交訂單後,訂單資料寫入訊息佇列,不能立即返回使用者訂單提交成功,需要在訊息佇列的訂單消費消費者程序真正處理完該訂單之後,甚至出庫後,再通過電子郵箱、簡訊通知使用者。 以免發生交易糾紛。類似場景:訂火車票、電影票。 2、削峰填谷,將短時間高併發產生的事物訊息儲存在訊息佇列中,然後後端服務根據自己的能力去消費這些訊息,這樣避免直接將後端服務打垮。 在電商秒殺、促銷業務場景中,合理使用訊息佇列可以有效抵禦促銷活動剛開始的大量訂單對系統的衝擊。 3、降低系統耦合性 使用訊息佇列可以降低系統的耦合性,因為模組之間不存在直接呼叫,那麼新增模組或者修改模組就對其他模組影響較小,系統擴充套件性會更好。 訊息佇列採用的是使用釋出-訂閱模式工作,消費傳送者(生產者)釋出訊息,一個或多個訊息接受者(消費者)訂閱訊息。   訊息佇列帶來的問題: 1、系統的可用性降低:系統可用性在某種程度上降低,在加入MQ之前,不用考慮訊息丟失或者MQ掛掉等情況,但是引入MQ之後會多考慮這些情況。 2、系統複雜性提高:加入MQ之後,你需要保證訊息沒有被重複消費,處理丟失的情況,保證訊息的順序性。 3、一致性問題:訊息非同步可以提高系統的響應速度,但是訊息並沒有正確消費訊息,就會導致資料不一致的情況。