日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JMS学习一(JMS介绍)

發(fā)布時(shí)間:2025/3/15 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JMS学习一(JMS介绍) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、JMS是個(gè)什么

1、JMS即Java消息服務(wù)(Java Message Service)應(yīng)用程序接口,是一個(gè)Java平臺(tái)中關(guān)于面向消息中間件(MOM)的API,用于在兩個(gè)應(yīng)用程序之間,或分布式系統(tǒng)中發(fā)送消息,進(jìn)行異步通信。Java消息服務(wù)是一個(gè)與具體平臺(tái)無關(guān)的API,絕大多數(shù)MOM提供商都對(duì)JMS提供支持。

2、JMS是一組消息服務(wù)的api即接口規(guī)范即數(shù)據(jù)庫的JDBC消息服務(wù)的JMS。

二、為什么要學(xué)習(xí),使用JMS

1、在JAVA中,如果兩個(gè)應(yīng)用程序之間對(duì)各自都不了解,甚至這兩個(gè)程序可能部署在不同的大洲上,那么它們之間如何發(fā)送消息呢?舉個(gè)例子,一個(gè)應(yīng)用程序A部署在印度,另一個(gè)應(yīng)用程序部署在美國,然后每當(dāng)A觸發(fā)某件事后,B想從A獲取一些更新信息。當(dāng)然,也有可能不止一個(gè)B對(duì)A的更新信息感興趣,可能會(huì)有N個(gè)類似B的應(yīng)用程序想從A中獲取更新的信息。在這種情況下,JAVA提供了最佳的解決方案-JMS,完美解決了上面討論的問題。JMS同樣適用于基于事件的應(yīng)用程序,如聊天服務(wù),它需要一種發(fā)布事件機(jī)制向所有與服務(wù)器連接的客戶端發(fā)送消息。JMS與RMI不同,發(fā)送消息的時(shí)候,接收者不需要在線。服務(wù)器發(fā)送了消息,然后就不管了;等到客戶端上線的時(shí)候,能保證接收到服務(wù)器發(fā)送的消息。這是一個(gè)很強(qiáng)大的解決方案,能處理當(dāng)今世界很多普遍問題。

三、JMS有什么優(yōu)勢(shì)

1、異步:JMS天生就是異步的,客戶端獲取消息的時(shí)候,不需要主動(dòng)發(fā)送請(qǐng)求,消息會(huì)自動(dòng)發(fā)送給可用的客戶端。

2、可靠:JMS保證消息只會(huì)遞送一次。大家都遇到過重復(fù)創(chuàng)建消息問題,而JMS能幫你避免該問題,只是避免而不是杜絕,所以在一些糟糕的環(huán)境下還是有可能會(huì)出現(xiàn)重復(fù)。

四、JMS消息傳送模型

在JMS API出現(xiàn)之前,大部分產(chǎn)品使用“點(diǎn)對(duì)點(diǎn)”和“發(fā)布/訂閱”中的任一方式來進(jìn)行消息通訊。JMS定義了這兩種消息發(fā)送模型的規(guī)范,它們相互獨(dú)立。任何JMS的提供者可以實(shí)現(xiàn)其中的一種或兩種模型,這是它們自己的選擇。JMS規(guī)范提供了通用接口保證我們基于JMS API編寫的程序適用于任何一種模型。讓我們更加詳細(xì)的看下這兩種消息傳送模型;

1、點(diǎn)對(duì)點(diǎn)消息傳送模型(P2P)

在點(diǎn)對(duì)點(diǎn)消息傳送模型中,應(yīng)用程序由消息隊(duì)列,發(fā)送者,接收者組成。每一個(gè)消息發(fā)送給一個(gè)特殊的消息隊(duì)列,該隊(duì)列保存了所有發(fā)送給它的消息(除了被接收者消費(fèi)掉的和過期的消息)。

點(diǎn)對(duì)點(diǎn)消息模型有如下特性:

(1)、每個(gè)消息只有一個(gè)接受者(自己測(cè)試了一下,可以有多個(gè)接受者,但是當(dāng)有多個(gè)接收者時(shí),每個(gè)接收者只能獲取隨機(jī)的幾條信息)

(2)、消息發(fā)送者和消息接受者并沒有時(shí)間依賴性。

(3)、當(dāng)消息發(fā)送者發(fā)送消息的時(shí)候,無論接收者程序在不在運(yùn)行,都能獲取到消息;

(4)、當(dāng)接收者收到消息的時(shí)候,會(huì)發(fā)送確認(rèn)收到通知(acknowledgement)。

(5)、點(diǎn)對(duì)點(diǎn)消息模型圖:

2、發(fā)布/訂閱消息傳送模型

在發(fā)布/訂閱消息模型中,發(fā)布者發(fā)布一個(gè)消息,該消息通過topic傳遞給所有的客戶端。在這種模型中,發(fā)布者和訂閱者彼此不知道對(duì)方,是匿名的且可以動(dòng)態(tài)發(fā)布和訂閱topic。topic主要用于保存和傳遞消息,且會(huì)一直保存消息直到消息被傳遞給客戶端。

發(fā)布/訂閱消息模型有如下特性:

(1)、一個(gè)消息可以傳遞給多個(gè)訂閱者

(2)、發(fā)布者和訂閱者有時(shí)間依賴性,只有當(dāng)客戶端創(chuàng)建訂閱后才能接受消息,且訂閱者需一直保持活動(dòng)狀態(tài)以接收消息。

(3)、為了緩和這樣嚴(yán)格的時(shí)間相關(guān)性,JMS允許訂閱者創(chuàng)建一個(gè)可持久化的訂閱。這樣,即使訂閱者沒有被激活(運(yùn)行),它也能接收到發(fā)布者的消息。

(4)、發(fā)布/訂閱消息模型圖:

?

?

五、接收消息

在JMS中,消息的接收可以使用以下兩種方式:

1、同步方式:使用同步方式接收消息的話,消息訂閱者調(diào)用receive()方法。在receive()中,消息未到達(dá)或在到達(dá)指定時(shí)間之前,方法會(huì)阻塞,直到消息可用。

(1)、 目的地是Queue

?

consumer = session.createConsumer(queue); Message message = consumer.receive(); //同步方式接收

?

?

(2)、目的地是Destination

?

consumer = session.createConsumer(destination); //同步方式接受信息,如果還沒有獲取到則會(huì)阻塞直到接收到信息 Message messages = consumer.receive();

?

?

2、異步方式:使用異步方式接收消息的話,消息訂閱者需注冊(cè)一個(gè)消息監(jiān)聽者,類似于事件監(jiān)聽器,只要消息到達(dá),JMS服務(wù)提供者會(huì)通過調(diào)用監(jiān)聽器的onMessage()遞送消息。

異步方式接收是使用了監(jiān)聽方式:

?

?

六、JMS編程接口

JMS應(yīng)用程序由如下基本模塊組成:

1、管理對(duì)象(Administered objects)-連接工廠(Connection Factories)和目的地(Destination)
2、連接對(duì)象(Connections)
3、會(huì)話(Sessions)
4、消息生產(chǎn)者(Message Producers)
5、消息消費(fèi)者(Message Consumers)
6、消息監(jiān)聽者(Message Listeners)

7、JMS管理對(duì)象

管理對(duì)象(Administered objects)是預(yù)先配置的JMS對(duì)象,由系統(tǒng)管理員為使用JMS的客戶端創(chuàng)建,主要有兩個(gè)被管理的對(duì)象:
連接工廠(ConnectionFactory)
目的地(Destination)
這兩個(gè)管理對(duì)象由JMS系統(tǒng)管理員通過使用Application Server管理控制臺(tái)創(chuàng)建,存儲(chǔ)在應(yīng)用程序服務(wù)器的JNDI名字空間或JNDI注冊(cè)表。

8、連接工廠(ConnectionFactory)

客戶端使用一個(gè)連接工廠對(duì)象連接到JMS服務(wù)提供者,它創(chuàng)建了JMS服務(wù)提供者和客戶端之間的連接。JMS客戶端(如發(fā)送者或接受者)會(huì)在JNDI名字空間中搜索并獲取該連接。使用該連接,客戶端能夠與目的地通訊,往隊(duì)列或話題發(fā)送/接收消息。讓我們用一個(gè)例子來理解如何發(fā)送消息:

9、目的地(Destination)

目的地指明消息被發(fā)送的目的地以及客戶端接收消息的來源。JMS使用兩種目的地,隊(duì)列和話題。

10、JMS連接

連接對(duì)象封裝了與JMS提供者之間的虛擬連接,如果我們有一個(gè)ConnectionFactory對(duì)象,可以使用它來創(chuàng)建一個(gè)連接。

?

//鏈接工廠 ActiveMQConnectionFactory connectionFactory = null; //鏈接對(duì)象 Connection connection = null; connectionFactory = new ActiveMQConnectionFactory("admin","admin","tcp://192.168.1.111:61616"); connection = connectionFactory.createConnection(); connection.start();

?

?

11、JMS 會(huì)話(Session)

Session是一個(gè)單線程上下文,用于生產(chǎn)和消費(fèi)消息,可以創(chuàng)建出消息生產(chǎn)者和消息消費(fèi)者。
Session對(duì)象實(shí)現(xiàn)了Session接口,在創(chuàng)建完連接后,我們可以使用它創(chuàng)建Session。

//第一個(gè)參數(shù)是否開啟事務(wù) true開啟 ,false不開啟事務(wù),如果開啟記得手動(dòng)提交 //參數(shù)二,表示的是簽收模式,一般使用的有自動(dòng)簽收和客戶端自己確認(rèn)簽收 session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);

?

?

12、JMS消息生產(chǎn)者

消息生產(chǎn)者由Session創(chuàng)建,用于往目的地發(fā)送消息。生產(chǎn)者實(shí)現(xiàn)MessageProducer接口,我們可以為目的地、隊(duì)列或話題創(chuàng)建生產(chǎn)者;

(1)、隊(duì)列(Queue)

Queue queue = session.createQueue("test_queue"); //為隊(duì)列創(chuàng)建消息生產(chǎn)者 MessageProducer producer = session.createProducer(queue);

?

(2)、目的地(Destination)

Destination destination = session.createQueue("test-queue"); //為目的地創(chuàng)建消息生產(chǎn)者 MessageProducer producer = session.createProducer(destination);

?

(1)(2)這兩種方式只能用在點(diǎn)對(duì)點(diǎn)消息模型

(3)、話題(Topic)

?

//創(chuàng)建話題 Topic topic = session.createTopic("myTopic.messages"); //為話題創(chuàng)建消息生產(chǎn)者 MessageProducer producer = session.createProducer(topic);

?

(3)、只能用在發(fā)布/訂閱消息模型上。


? ?創(chuàng)建完消息生產(chǎn)者后,可以使用send方法發(fā)送消息:

//創(chuàng)建消息 TextMessage message = session.createTextMessage(); message.setText("測(cè)試隊(duì)列消息"+i); //發(fā)送消息到目的地 producer.send(message);

?

13、JMS消息消費(fèi)者

消息消費(fèi)者由Session創(chuàng)建,用于接收目的地發(fā)送的消息。消費(fèi)者實(shí)現(xiàn)MessageConsumer接口,我們可以為目的地、隊(duì)列或話題創(chuàng)建消費(fèi)者;

(1)、隊(duì)列(Queue)

Queue queue = session.createQueue("test_queue"); //隊(duì)列(目的地,消費(fèi)者消費(fèi)消息的地方) MessageConsumer consumer = session.createConsumer(queue); //消息消費(fèi)者

?

(2)、目的地(Destination)

//消息目的地 Destination destination = session.createQueue("test-queue"); //消息消費(fèi)者 MessageConsumer consumer = session.createConsumer(destination);

?

(3)、話題(Topic)

//創(chuàng)建話題 Topic topic = session.createTopic("myTopic.messages"); //為話題創(chuàng)建消費(fèi)者 MessageConsumer consumer = session.createConsumer(topic);

?

?

14、JMS消息監(jiān)聽器(消息監(jiān)聽這種方式也就是消息的異步接收方式)
JMS消息監(jiān)聽器是消息的默認(rèn)事件處理者,他實(shí)現(xiàn)了MessageListener接口,該接口包含一個(gè)onMessage方法,在該方法中需要定義消息達(dá)到后的具體動(dòng)作。通過調(diào)用setMessageListener方法我們給指定消費(fèi)者定義了消息監(jiān)聽器.

?

(1)、TextMessage

consumer.setMessageListener(new MessageListener(){ @Override public void onMessage(Message message) { TextMessage textMessage = (TextMessage)message; try { String value = textMessage.getText(); System.out.println("value: "+value); } catch (JMSException e) { // TODO Auto-generated catch block e.printStackTrace(); } } });

?


(2)、ObjectMessage

consumer.setMessageListener(new MessageListener(){ @Override public void onMessage(Message message){ try { TestBean tbean =(TestBean)((ObjectMessage)message).getObject(); System.out.println("tbean: "+tbean); if(null != message) { System.out.println("收到信息1: "+tbean.getName()); } } catch (JMSException e) { // TODO Auto-generated catch block e.printStackTrace(); } } });

?

?

七、JMS消息結(jié)構(gòu)

JMS客戶端使用JMS消息與系統(tǒng)通訊,JMS消息雖然格式簡單但是非常靈活, JMS消息由三部分組成:

1、消息頭

JMS消息頭預(yù)定義了若干字段用于客戶端與JMS提供者之間識(shí)別和發(fā)送消息,預(yù)編譯頭如下:
–?JMSDestination?:?消息發(fā)送的目的地,主要是指Queue和Topic,由session創(chuàng)建而由生產(chǎn)者的send方法設(shè)置.
– JMSDeliveryMode:傳送模式:有兩種即久模式和非持久模式。一條持久性的消息應(yīng)該被傳輸"一次僅僅一次",這就意味著如果JMS提供者出現(xiàn)故障,該消息并不會(huì)丟失,它會(huì)在服務(wù)器恢復(fù)之后再次傳遞。一條非持久的消息最多會(huì)傳遞一次,這意味著服務(wù)器出現(xiàn)故障,該消息將永遠(yuǎn)丟失。由session穿件由消息生產(chǎn)者的send方法設(shè)置
–?JMSMessageID:唯一識(shí)別每個(gè)消息的標(biāo)識(shí),由JMS消息生產(chǎn)者產(chǎn)生。由send方法設(shè)置
–?JMSTimestamp:一個(gè)JMS Provider在調(diào)用send()方法時(shí)自動(dòng)設(shè)置,它是消息被發(fā)送和消費(fèi)者實(shí)際接收的時(shí)間差。由客戶端設(shè)置
–?JMSCorrelationID:用來連接到另外一個(gè)消息,典型的應(yīng)用是在回復(fù)消息中連接到原消息。在大多數(shù)情況下,JMSCorrelationID用于將一條消息標(biāo)記為對(duì)JMSMessageID標(biāo)示的上一條消息的應(yīng)答,不過,JMSCorrelationID可以是任何值,不僅僅是JMSMessageID。由客戶端設(shè)置
–?JMSReplyTo:提供本消息回復(fù)消息的目的地址,由客戶端設(shè)置
–?JMSRedelivered:如果一個(gè)客戶端收到一個(gè)設(shè)置了JMSRedelivered屬性的消息,則表示可能客戶端曾經(jīng)在早些時(shí)候收到過該消息,但并沒有簽收(acknowledged)。如果該消息被重新傳送,JMSRedelivered=true 否則 JMSRedelivered=flase 。由JMS Provider設(shè)置
–?JMSType:消息類型的標(biāo)識(shí)符,由客戶端設(shè)置
–?JMSExpiration:消息過期時(shí)間,等于Destination的send方法中的timeToLive值加上發(fā)送時(shí)刻的GMT的時(shí)間值。如果timeToLive值等于零,則JMSExpiration被設(shè)置為零,表示該消息永不過期。如果發(fā)送后,在消息過期時(shí)間之后消息還沒有被發(fā)送到目的地,則該消息被清除。由send方法設(shè)置
–?JMSPriority:消息優(yōu)先級(jí),從0-9十個(gè)級(jí)別,0-4是普通消息,5-9是加急消息。JMS不要求JMS Provider嚴(yán)格按照這十個(gè)優(yōu)先級(jí)發(fā)送消息,但必須保證加急消息要先于普通消息到達(dá),默認(rèn)是4級(jí)。由send方法設(shè)置
一個(gè)消息的消息頭有這些屬性,我們可以按照需要對(duì)這個(gè)消息的消息進(jìn)行設(shè)計(jì),在將這個(gè)消息使用消息生產(chǎn)者的send()方法發(fā)送到消息服務(wù)上。

2、消息屬性

我們可以給消息設(shè)置自定義屬性,這些屬性主要是提供給應(yīng)用程序的。對(duì)于實(shí)現(xiàn)消息過濾功能,消息屬性非常有用,JMS API定義了一些標(biāo)準(zhǔn)屬性,JMS服務(wù)提供者可以選擇性的提供部分標(biāo)準(zhǔn)屬性。

3、消息體

在消息體中,JMS API定義了五種類型的消息格式,讓我們可以以不同的形式發(fā)送和接受消息,并提供了對(duì)已有消息格式的兼容。不同的消息類型如下:
Text message : javax.jms.TextMessage,表示一個(gè)文本對(duì)象。
Object message : javax.jms.ObjectMessage,表示一個(gè)JAVA對(duì)象。
Bytes message : javax.jms.BytesMessage,表示字節(jié)數(shù)據(jù)。
Stream message :javax.jms.StreamMessage,表示java原始值數(shù)據(jù)流。
Map message : javax.jms.MapMessage,表示鍵值對(duì)。

總結(jié)

以上是生活随笔為你收集整理的JMS学习一(JMS介绍)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。