消息中間件
消息中間件有很多的用途和優(yōu)點(diǎn):
1. 將數(shù)據(jù)從一個應(yīng)用程序傳送到另一個應(yīng)用程序罐栈,或者從軟件的一個模塊傳送到另外一個模塊允坚;
2. 負(fù)責(zé)建立網(wǎng)絡(luò)通信的通道霎箍,進(jìn)行數(shù)據(jù)的可靠傳送祈匙。
3. 保證數(shù)據(jù)不重發(fā)吐限,不丟失
4. 能夠?qū)崿F(xiàn)跨平臺操作鲜侥,能夠?yàn)椴煌僮飨到y(tǒng)上的軟件集成技工數(shù)據(jù)傳送服務(wù)
ActiveMQ是由Apache出品的,一款最流行的诸典,能力強(qiáng)勁的開源消息總線描函。ActiveMQ是一個完全支持JMS1.1和J2EE 1.4規(guī)范的 JMS Provider實(shí)現(xiàn),它非常快速舀寓,支持多種語言的客戶端和協(xié)議胆数,而且可以非常容易的嵌入到企業(yè)的應(yīng)用環(huán)境中,并有許多高級功能基公。
ActiveMQ特性列表
多種語言和協(xié)議編寫客戶端幅慌。語言: Java, C, C++, C#, Ruby, Perl, Python, PHP。應(yīng)用協(xié)議: OpenWire,Stomp REST,WS Notification,XMPP,AMQP
完全支持JMS1.1和J2EE 1.4規(guī)范 (持久化,XA消息,事務(wù))
對Spring的支持,ActiveMQ可以很容易內(nèi)嵌到使用Spring的系統(tǒng)里面去,而且也支持Spring2.0的特性
通過了常見J2EE服務(wù)器(如 Geronimo,JBoss 4, GlassFish,WebLogic)的測試,其中通過JCA 1.5 resource adaptors的配置,可以讓ActiveMQ可以自動的部署到任何兼容J2EE 1.4 商業(yè)服務(wù)器上
支持多種傳送協(xié)議:in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA
支持通過JDBC和journal提供高速的消息持久化
從設(shè)計(jì)上保證了高性能的集群,客戶端-服務(wù)器,點(diǎn)對點(diǎn)
支持Ajax
支持與Axis的整合
可以很容易得調(diào)用內(nèi)嵌JMS provider,進(jìn)行測試
ACK:
一轰豆,消息的確認(rèn)模式:
JMS API中約定了Client端可以使用四種ACK_MODE,在javax.jms.Session接口中:
非事務(wù)會話可做如下設(shè)置:
1.Session.AUTO_ACKNOWLEDGE(自動確認(rèn)模式)
當(dāng)消息成功的從receive方法返回時胰伍,或者從MessageListener接口的onMessage方法成功返回時,會話自動確認(rèn)客戶端的消息接收酸休。
2.Session.CLIENT_ACKNOWLEDGE(客戶端確認(rèn)模式)
客戶端通過調(diào)用消息的acknowledge方法簽收消息骂租。在這種模式中,簽收是在會話層上進(jìn)行:簽收一個已消費(fèi)的消息會自動地簽收這個Session所有已消費(fèi)消息的收條斑司。
例如渗饮,如果一個消息消費(fèi)者消費(fèi)了10個消息,然后確認(rèn)第5個消息宿刮,那么所有10個消息都會被確認(rèn)互站。
3.?Session.DUPS_OK_ACKNOWLEDGE(延時/批量確認(rèn)模式)
這種確認(rèn)方式允許JMS不必急于確認(rèn)收到的消息,允許在收到多個消息之后一次完成確認(rèn),與Auto_AcKnowledge相比,這種確認(rèn)方式在某些情況下可能更有效,因?yàn)闆]有確認(rèn),當(dāng)系統(tǒng)崩潰或者網(wǎng)絡(luò)出現(xiàn)故障的時候,消息可以被重新傳遞.
這種方式會引起消息的重復(fù),但是降低了Session的開銷僵缺,所以只有客戶端能容忍重復(fù)的消息胡桃,才可使用。(如果ActiveMQ再次傳送同一消息磕潮,那么消息頭中的JMSRedelivered將被設(shè)置為true)
我們在開發(fā)JMS應(yīng)用程序的時候,會經(jīng)常使用到上述ACK_MODE,其中"INDIVIDUAL_ACKNOWLEDGE?"只有ActiveMQ支持,當(dāng)然開發(fā)者也可以使用它. ACK_MODE描述了Consumer與broker確認(rèn)消息的方式(時機(jī)),比如當(dāng)消息被Consumer接收之后,Consumer將在何時確認(rèn)消息翠胰。對于broker而言,只有接收到ACK指令,才會認(rèn)為消息被正確的接收或者處理成功了,通過ACK自脯,可以在consumer與Broker之間建立一種簡單的“擔(dān)敝埃”機(jī)制.
我們需要在創(chuàng)建Session時指定ACK_MODE,由此可見,ACK_MODE將是session共享的,意味著一個session下所有的 consumer都使用同一種ACK_MODE。在創(chuàng)建Session時,開發(fā)者不能指定除ACK_MODE列表之外的其他值.如果此session為事務(wù)類型,用戶指定的ACK_MODE將被忽略,而強(qiáng)制使用"SESSION_TRANSACTED"類型;如果session非事務(wù)類型時,也將不能將 ACK_MODE設(shè)定為"SESSION_TRANSACTED",畢竟這是相悖的.
消費(fèi)者和broker通訊最終實(shí)現(xiàn)消息確認(rèn)膏潮,消息確認(rèn)機(jī)制一共有5種锻狗,4種jms的和1種activemq補(bǔ)充的,AUTO_ACKNOWLEDGE(自動確認(rèn))焕参、CLIENT_ACKNOWLEDGE(客戶確認(rèn))屋谭、DUPS_OK_ACKNOWLEDGE(批量確認(rèn))、SESSION_TRANSACTED(事務(wù)確認(rèn))龟糕、INDIVIDUAL_ACKNOWLEDGE(單條確認(rèn))桐磁,consumer在不同的模式下會發(fā)不同的命令到broker,broker再根據(jù)不同的命令進(jìn)行操作讲岁,如果consumer正常發(fā)送ack命令給broker我擂,broker會從topic移除消息并銷毀衬以,如果未從消費(fèi)者接受到確認(rèn)命令,broker會將消息轉(zhuǎn)移到dlq隊(duì)列(dead letter queue)校摩,并根據(jù)delivery mode進(jìn)行重試或報(bào)異常看峻。
二、ActiveMQ的本地事務(wù)
在一個JMS客戶端衙吩,可以使用本地事務(wù)來組合消息的發(fā)送和接收互妓。JMS Session接口提供了commit和rollback方法。事務(wù)提交意味著生產(chǎn)的所有消息被發(fā)送坤塞,消費(fèi)的所有消息被確認(rèn)冯勉;事務(wù)回滾意味著生產(chǎn)的所有消息被銷毀,消費(fèi)的所有消息被恢復(fù)并重新提交摹芙,除非它們已經(jīng)過期灼狰。 事務(wù)性的會話總是牽涉到事務(wù)處理中,commit或rollback方法一旦被調(diào)用浮禾,一個事務(wù)就結(jié)束了交胚,而另一個事務(wù)被開始。關(guān)閉事務(wù)性會話將回滾其中的事務(wù)盈电。 需要注意的是蝴簇,如果使用請求/回復(fù)機(jī)制,即發(fā)送一個消息匆帚,同時希望在同一個事務(wù)中等待接收該消息的回復(fù)军熏,那么程序?qū)⒈粧炱穑驗(yàn)橹钡绞聞?wù)提交卷扮,發(fā)送操作才會真正執(zhí)行。 需要注意的還有一個均践,消息的生產(chǎn)和消費(fèi)不能包含在同一個事務(wù)中晤锹。
在事務(wù)狀態(tài)下進(jìn)行發(fā)送操作,消息并未真正投遞到中間件彤委,而只有進(jìn)行session.commit操作之后鞭铆,消息才會發(fā)送到中間件,再轉(zhuǎn)發(fā)到適當(dāng)?shù)南M(fèi)者進(jìn)行處理焦影。如果是調(diào)用rollback操作车遂,則表明,當(dāng)前事務(wù)期間內(nèi)所發(fā)送的消息都取消掉斯辰。
2舶担、關(guān)于ActiveMQ本地事務(wù)的用法
[java]view plaincopy
publicclassSender?{
publicstaticvoidmain(String[]?args)throwsException?{
//?1、建立ConnectionFactory工廠對象彬呻,需要填入用戶名衣陶,密碼柄瑰,以及連接的地址
//?僅使用默認(rèn)。端口號為"tcp://localhost:61616"
ConnectionFactory?connectionFactory?=newActiveMQConnectionFactory(
"zhangsan",//?ActiveMQConnectionFactory.DEFAULT_USER,
"123",//?ActiveMQConnectionFactory.DEFAULT_PASSWORD,
"tcp://localhost:61616");
//?2剪况、通過ConnectionFactory工廠對象創(chuàng)建一個Connection連接
//?并且調(diào)用Connection的start方法開啟連接,Connection默認(rèn)是不開啟的
Connection?connection?=?connectionFactory.createConnection();
connection.start();
//?3教沾、通過Connection對象創(chuàng)建Session會話(上下文環(huán)境對象),
//?參數(shù)一译断,表示是否開啟事務(wù)
//?參數(shù)二授翻,表示的是簽收模式,一般使用的有自動簽收和客戶端自己確認(rèn)簽收
//?第一個參數(shù)設(shè)置為true孙咪,表示開啟事務(wù)
//?開啟事務(wù)后堪唐,記得要手動提交事務(wù)
Session?session?=?connection.createSession(Boolean.TRUE,
Session.AUTO_ACKNOWLEDGE);
//?4、通過Session創(chuàng)建Destination對象该贾,指的是一個客戶端用來指定生產(chǎn)消息目標(biāo)和消費(fèi)消息來源的對象羔杨。
//?在PTP模式中,Destination指的是Queue
//?在發(fā)布訂閱模式中,Destination指的是Topic
Destination?destination?=?session.createQueue("queue1");
//?5杨蛋、使用Session來創(chuàng)建消息對象的生產(chǎn)者或者消費(fèi)者
MessageProducer?messageProducer?=?session.createProducer(destination);
//?6兜材、如果是,生產(chǎn)者逞力,使用MessageProducer的setDeliverMode方法設(shè)置曙寡,消息的持久化和非持久化
messageProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
//?7、最后使用JMS規(guī)范的TextMessage形式創(chuàng)建數(shù)據(jù)(通過Session對象)
//?并利用MessageProducer的send方法發(fā)送數(shù)據(jù)
for(inti?=0;?i?<5;?i++)?{
TextMessage?textMessage?=?session.createTextMessage();
textMessage.setText("我是消息"+?i);
messageProducer.send(textMessage);
}
//?手動提交開啟的事務(wù)
session.commit();
//?釋放連接
if(connection?!=null)?{
connection.close();
}
}
}
為什么commit之后寇荧,不會有持久的消息重新傳送呢?
原因在于commit操作會自動將為簽收確認(rèn)的消息進(jìn)行簽收確認(rèn)举庶,如果是當(dāng)前接收但未簽收確認(rèn)的消息,都會被確認(rèn)處理揩抡。因而在commit之后不會有持久化的消息出現(xiàn)户侥。
.對于consumer而言,消息接收到之后,需要手動的使用commit,否則JMS Provider會認(rèn)為消息沒有被接收,導(dǎo)致重發(fā),因此你可以認(rèn)為commit就是一個消息確認(rèn)操作.
三.消費(fèi)消息的風(fēng)格
Consumer消費(fèi)消息的風(fēng)格有2種: 同步/異步..使用consumer.receive()就是同步,使用messageListener就是異步峦嗤;在同一個consumer中蕊唐,我們不能使用使用這2種風(fēng)格,比如在使用listener的情況下烁设,當(dāng)調(diào)用receive()方法將會獲得一個Exception
四 .指定消息傳送模式
ActiveMQ 支持兩種消息傳送模式:PERSISTENT 和NON_PERSISTENT 兩種替梨。
1.PERSISTENT(持久性消息)
這是 ActiveMQ 的默認(rèn)傳送模式,此模式保證這些消息只被傳送一次和成
功使用一次装黑。對于這些消息副瀑,可靠性是優(yōu)先考慮的因素×堤罚可靠性的另一個重要方面是確
保持久性消息傳送至目標(biāo)后糠睡,消息服務(wù)在向消費(fèi)者傳送它們之前不會丟失這些消息。這
意味著在持久性消息傳送至目標(biāo)時疚颊,消息服務(wù)將其放入持久性數(shù)據(jù)存儲铜幽。如果消息服務(wù)
由于某種原因?qū)е率≈托唬梢曰謴?fù)此消息并將此消息傳送至相應(yīng)的消費(fèi)者。雖然這樣
增加了消息傳送的開銷除抛,但卻增加了可靠性狮杨。
2.NON_PERSISTENT(非持久性消息)
保證這些消息最多被傳送一次。對于這些消息到忽,可靠性并非主要的考慮因素橄教。
此模式并不要求持久性的數(shù)據(jù)存儲,也不保證消息服務(wù)由于某種原因?qū)е率『笙⒉?/p>
會丟失喘漏。
什么情況下使用ActiveMQ?
多個項(xiàng)目之間集成
(1) 跨平臺
(2) 多語言
(3) 多項(xiàng)目
降低系統(tǒng)間模塊的耦合度护蝶,解耦
(1) 軟件擴(kuò)展性
系統(tǒng)前后端隔離
(1) 前后端隔離,屏蔽高安全區(qū)