其實這個問題有個面試官問過我,但被我搪塞過去了。其實說到底是那會兒對這個玩意不是特別熟悉,僅僅是聽說過。現如今,已經了解了很多了,所以拿出來說一說。
其實這道題屬於偏“業務”類型的問題。延遲隊列首先是個消息隊列,其次是個帶延遲功能的消息隊列,你這么理解就對了。相對於普通消息隊列,延遲隊列中的消息除了消息本身外,還要有一個重要元素就是說明這條消息應該何時被消費掉!也就說在指定時間消費掉指定消息。
首先說這玩意能解決什么問題吧。
- 搶了一個小米手機,超過30分鍾未支付,訂單自動作廢
- 有些退款的訂單,那么退款到賬是如何檢測的
- 注冊后到現在已經30天的用戶,如何發短信撩動
這些業務場景就是典型的需要延遲隊列的case。就比如說第一個案例,如果沒有延遲隊列怎么辦?就是寫腳本用定時器的方法去輪訓,只能如此這樣做,沒有更好的辦法。假如延遲隊列后,這件事情就變得好玩了。
好了,回答了面試官的第一個問題:知道延遲隊列嗎?或者說“訂單30分鍾超時,如何做?”這個問題得到了解決。
第二個問題,好了現在你要做了,作為phper你准備如何實現延遲隊列?
kafka是不可能的,我光聽過名字,連摸都沒摸過。還是用redis湊合做吧。redis中有個比較屌的數據結構叫做zset,給每個鍵都添加了一個score的元素,就是分數。我們可以拿時間戳當作score給這個key,然后通過zrevrange獲取key的時候指定score范圍即可。這樣,就可以通過redis實現了一個最簡單的延遲隊列,而且,吞吐量也不算特別小,足夠一般公司支撐一段時間業務了。