爲什麼使用消息隊列?
這是一個很嚴肅的問題。
- 系統之間解除耦合,可以讓不同語言編寫的系統通信交互
- 保證服務器負載不會飆升。高大上一點就是流量削峯。
- 讓程序變成異步,提高響應速度。把費時任務放到另一個進程或線程去執行。
消息隊列用什麼?
- redis實現
剛開始學習redis時,一看這個鏈表不就是給隊列準備的嗎?
所以,一心扎進去,要寫個隊列出來。結果就看到redis作者說redis不是拿來搞這個的。
哈哈,所以就作罷。 - RabbitMQ
- Kafka
關於消息隊列,我本身也是剛開始琢磨和入門,就不亂做對比。
一般來說kafka用於日誌。
RabbitMQ
看了官方的案例後,很是心動。就想着直接用到項目裏。
幸虧,我喜歡把文檔看完。
結尾有這樣一句話:以上案例不能直接用於生產環境。額啊呀喔哦,一庫。
注意事項:
- 連接管理
- 錯誤處理
- 連接恢復
- 併發
- 度量收集
如何保證消息不丟失?
如果消費者使用消息的時候,消息未處理成功,進程死掉。
那麼消息隊列,在消費者取信息時直接刪除就會有丟失消息的風險。
所以RabbitMQ引入了消費者ACK。即不發ACK,消息就不會刪除。
setting the fourth parameter to basic_consume to false (true means no ack)
設置basic_consume的第四個參數爲false(true意味着不發ACK)
使用命令查看沒有得到ACK的消息
sudo rabbitmqctl list_queues name messages_ready messages_unacknowledged
如何保證ACK丟失,代碼不出錯?
我的想法是把每個任務做標記,已經處理過的任務,再次遇到,直接返回ack。
如何保證RabbitMQ掛掉,隊列消息不丟失?
這就用到了持久化的思想,將隊列和消息都標記爲持久。
說到這裏就想到了redis的RDB和AOF。哈哈
設置queue_declare的第三個參數爲true
保證新發布的隊列持久。不能對已經發布的隊列更改
設置消息持久,PHP版本代碼
$ msg = new AMQPMessage(
$ data,array('delivery_mode' => AMQPMessage :: DELIVERY_MODE_PERSISTENT)
);
未完待續。。。