1、如何使用ActiveMQ解決分布式事務(wù)?
在互聯(lián)網(wǎng)應(yīng)用中,基本都會有用戶注冊的功能。在注冊的同時,我們會做出如下操作:
● 收集用戶錄入信息,保存到數(shù)據(jù)庫
● 向用戶的手機或郵箱發(fā)送驗證碼
如果是傳統(tǒng)的集中式架構(gòu),實現(xiàn)這個功能非常簡單:開啟一個本地事務(wù),往本地數(shù)據(jù)庫中插入一條用戶數(shù)據(jù),發(fā)送驗證碼,提交事物。但是在分布式架構(gòu)中,用戶和發(fā)送驗證碼是兩個獨立的服務(wù),它們都有各自的數(shù)據(jù)庫,那么就不能通過本地事物保證操作的原子性。這時我們就需要用到ActiveMQ(消息隊列)來為我們實現(xiàn)這個需求。在用戶進行注冊操作的時候,我們?yōu)樵摬僮鲃?chuàng)建一條消息,當(dāng)用戶信息保存成功時,把這條消息發(fā)送到消息隊列。驗證碼系統(tǒng)會監(jiān)聽消息,一旦接受到消息,就會給該用戶發(fā)送驗證碼。
解決方法很簡單:增加消息狀態(tài)表。通俗來說就是一個賬本,用來記錄消息的處理狀態(tài),每次處理消息之前,都去狀態(tài)表中查詢一次。如果已經(jīng)有相同的消息存在,那么不處理,可以防止重復(fù)發(fā)送。
ActiveMQ、RabbitMQ、kafka。
RabbitMQ是使用Erlang編寫的一個開源的消息隊列,本身支持很多的協(xié)議:AMQP,XMPP,SMTP,STOMP,也正因如此,它非常重量級,更適合于企業(yè)級的開發(fā)。同時實現(xiàn)了Broker構(gòu)架,這意味著消息在發(fā)送給客戶端時先在中心隊列排隊。對路由,負載均衡或者數(shù)據(jù)持久化都有很好的支持。
ActiveMQ是Apache下的一個子項目。類似于ZeroMQ,它能夠以代理人和點對點的技術(shù)實現(xiàn)隊列。同時類似于RabbitMQ,它少量代碼就可以高效地實現(xiàn)高級應(yīng)用場景。
Kafka是Apache下的一個子項目,是一個高性能跨語言分布式發(fā)布/訂閱消息隊列系統(tǒng),而Jafka是在Kafka之上孵化而來的,即Kafka的一個升級版。具有以下特性:快速持久化,可以在O(1)的系統(tǒng)開銷下進行消息持久化;高吞吐,在一臺普通的服務(wù)器上既可以達到10W/s的吞吐速率;完全的分布式系統(tǒng),Broker、Producer、Consumer都原生自動支持分布式,自動實現(xiàn)負載均衡;支持Hadoop數(shù)據(jù)并行加載,對于像Hadoop的一樣的日志數(shù)據(jù)和離線分析系統(tǒng),但又要求實時處理的限制,這是一個可行的解決方案。Kafka通過Hadoop的并行加載機制統(tǒng)一了在線和離線的消息處理。Apache Kafka相對于ActiveMQ是一個非常輕量級的消息系統(tǒng),除了性能非常好之外,還是一個工作良好的分布式系統(tǒng)。
● MQ選型對比圖
4、ActiveMQ如果消息發(fā)送失敗怎么辦?
Activemq有兩種通信方式,點到點形式和發(fā)布訂閱模式。
如果是點到點模式的話,如果消息發(fā)送不成功,此消息默認會保存到activemq服務(wù)端知道有消費者將其消費,所以此時消息是不會丟失的。
如果是發(fā)布訂閱模式的通信方式,默認情況下只通知一次,如果接收不到此消息就沒有了。這種場景只適用于對消息送達率要求不高的情況。如果要求消息必須送達不可以丟失的話,需要配置持久訂閱。每個訂閱端定義一個id,在訂閱是向activemq注冊。發(fā)布消息和接收消息時需要配置發(fā)送模式為持久化。此時如果客戶端接收不到消息,消息會持久化到服務(wù)端,直到客戶端正常接收后為止。