版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
消息隊(duì)列:ActiveMQ:ActiveMQ消息類(lèi)型:點(diǎn)對(duì)點(diǎn)與發(fā)布訂閱1消息隊(duì)列基礎(chǔ)概念1.1消息隊(duì)列簡(jiǎn)介消息隊(duì)列是一種應(yīng)用程序間通信(IPC)的模式,它允許消息在發(fā)送者和接收者之間異步傳遞。這種模式在分布式系統(tǒng)中特別有用,因?yàn)樗梢越怦罘?wù),提高系統(tǒng)的可擴(kuò)展性和容錯(cuò)性。消息隊(duì)列通常包含一個(gè)隊(duì)列,用于存儲(chǔ)消息,直到它們被消費(fèi)。發(fā)送者將消息發(fā)送到隊(duì)列,而接收者從隊(duì)列中取出并處理消息。1.1.1優(yōu)點(diǎn)解耦:發(fā)送者和接收者不需要同時(shí)在線。異步通信:接收者可以異步處理消息,提高系統(tǒng)響應(yīng)速度。流量削峰:在高流量時(shí),消息隊(duì)列可以存儲(chǔ)消息,避免系統(tǒng)過(guò)載。冗余:消息隊(duì)列可以持久化消息,確保即使接收者失敗,消息也不會(huì)丟失。1.1.2缺點(diǎn)復(fù)雜性:引入了額外的系統(tǒng)組件,增加了系統(tǒng)的復(fù)雜性。延遲:消息從發(fā)送到處理可能有延遲。成本:需要維護(hù)額外的基礎(chǔ)設(shè)施。1.2ActiveMQ概述ActiveMQ是Apache出品的、遵循AMQP1.0協(xié)議的、功能豐富的消息中間件。它支持多種消息傳遞模式,包括點(diǎn)對(duì)點(diǎn)(P2P)和發(fā)布/訂閱(Pub/Sub)。ActiveMQ還提供了許多高級(jí)特性,如持久化、事務(wù)、集群、虛擬主機(jī)等,使其成為企業(yè)級(jí)應(yīng)用的理想選擇。1.2.1特性支持多種協(xié)議:如AMQP、MQTT、STOMP等。高可用性:支持集群和主從模式,確保消息傳遞的可靠性。消息持久化:即使服務(wù)器重啟,消息也不會(huì)丟失。虛擬主機(jī):可以創(chuàng)建多個(gè)虛擬主機(jī),隔離不同的應(yīng)用程序。1.3消息隊(duì)列的工作原理消息隊(duì)列的工作原理基于生產(chǎn)者-消費(fèi)者模型。生產(chǎn)者將消息發(fā)送到隊(duì)列,而消費(fèi)者從隊(duì)列中取出并處理消息。隊(duì)列充當(dāng)生產(chǎn)者和消費(fèi)者之間的緩沖區(qū),確保消息的可靠傳遞。1.3.1生產(chǎn)者生產(chǎn)者是消息的發(fā)送者。它將消息發(fā)送到消息隊(duì)列,然后繼續(xù)執(zhí)行其他任務(wù),無(wú)需等待消息被處理。1.3.2消費(fèi)者消費(fèi)者是消息的接收者。它從消息隊(duì)列中取出消息并處理。消費(fèi)者可以是多個(gè),這意味著隊(duì)列中的消息可以被多個(gè)消費(fèi)者處理。1.3.3隊(duì)列隊(duì)列是消息的存儲(chǔ)區(qū)。它接收生產(chǎn)者發(fā)送的消息,并將它們存儲(chǔ)直到被消費(fèi)者取出。隊(duì)列可以是持久的,這意味著即使服務(wù)器重啟,隊(duì)列中的消息也不會(huì)丟失。1.3.4示例:使用Java發(fā)送和接收消息下面是一個(gè)使用ActiveMQ發(fā)送和接收消息的簡(jiǎn)單示例。我們將使用Java和ActiveMQ的JMSAPI。發(fā)送消息importjavax.jms.Connection;
importjavax.jms.ConnectionFactory;
importjavax.jms.Destination;
importjavax.jms.MessageProducer;
importjavax.jms.Session;
importjavax.jms.TextMessage;
importorg.apache.activemq.ActiveMQConnectionFactory;
publicclassJMSProducer{
publicstaticvoidmain(String[]args)throwsException{
//創(chuàng)建連接工廠
ConnectionFactoryconnectionFactory=newActiveMQConnectionFactory("tcp://localhost:61616");
//創(chuàng)建連接
Connectionconnection=connectionFactory.createConnection();
//啟動(dòng)連接
connection.start();
//創(chuàng)建會(huì)話
Sessionsession=connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//創(chuàng)建隊(duì)列
Destinationdestination=session.createQueue("MyQueue");
//創(chuàng)建消息生產(chǎn)者
MessageProducerproducer=session.createProducer(destination);
//創(chuàng)建消息
TextMessagemessage=session.createTextMessage("Hello,ActiveMQ!");
//發(fā)送消息
producer.send(message);
//關(guān)閉資源
producer.close();
session.close();
connection.close();
}
}接收消息importjavax.jms.Connection;
importjavax.jms.ConnectionFactory;
importjavax.jms.Destination;
importjavax.jms.Message;
importjavax.jms.MessageConsumer;
importjavax.jms.Session;
importjavax.jms.TextMessage;
importorg.apache.activemq.ActiveMQConnectionFactory;
publicclassJMSSubscriber{
publicstaticvoidmain(String[]args)throwsException{
//創(chuàng)建連接工廠
ConnectionFactoryconnectionFactory=newActiveMQConnectionFactory("tcp://localhost:61616");
//創(chuàng)建連接
Connectionconnection=connectionFactory.createConnection();
//啟動(dòng)連接
connection.start();
//創(chuàng)建會(huì)話
Sessionsession=connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//創(chuàng)建隊(duì)列
Destinationdestination=session.createQueue("MyQueue");
//創(chuàng)建消息消費(fèi)者
MessageConsumerconsumer=session.createConsumer(destination);
//接收消息
Messagemessage=consumer.receive();
//檢查消息類(lèi)型
if(messageinstanceofTextMessage){
TextMessagetextMessage=(TextMessage)message;
//打印消息內(nèi)容
System.out.println("Receivedmessage:"+textMessage.getText());
}
//關(guān)閉資源
consumer.close();
session.close();
connection.close();
}
}在這個(gè)示例中,我們首先創(chuàng)建了一個(gè)連接工廠,然后使用這個(gè)工廠創(chuàng)建了一個(gè)連接。我們創(chuàng)建了一個(gè)會(huì)話,然后使用會(huì)話創(chuàng)建了一個(gè)隊(duì)列。生產(chǎn)者使用會(huì)話創(chuàng)建了一個(gè)消息,并將其發(fā)送到隊(duì)列。消費(fèi)者從隊(duì)列中接收消息并處理。1.4點(diǎn)對(duì)點(diǎn)與發(fā)布訂閱消息隊(duì)列有兩種主要的消息傳遞模式:點(diǎn)對(duì)點(diǎn)(P2P)和發(fā)布/訂閱(Pub/Sub)。1.4.1點(diǎn)對(duì)點(diǎn)(P2P)在點(diǎn)對(duì)點(diǎn)模式中,消息被發(fā)送到隊(duì)列,然后由一個(gè)消費(fèi)者接收。一旦消息被接收,它就會(huì)從隊(duì)列中移除。這意味著,如果多個(gè)消費(fèi)者訂閱了同一個(gè)隊(duì)列,每個(gè)消息只會(huì)被其中一個(gè)消費(fèi)者接收。1.4.2發(fā)布/訂閱(Pub/Sub)在發(fā)布/訂閱模式中,消息被發(fā)送到主題,然后由所有訂閱了該主題的消費(fèi)者接收。這意味著,如果多個(gè)消費(fèi)者訂閱了同一個(gè)主題,每個(gè)消費(fèi)者都會(huì)接收到每條消息的副本。1.4.3示例:使用Java發(fā)送和接收消息(發(fā)布/訂閱)下面是一個(gè)使用ActiveMQ發(fā)送和接收消息的發(fā)布/訂閱模式的示例。我們將使用Java和ActiveMQ的JMSAPI。發(fā)布消息importjavax.jms.Connection;
importjavax.jms.ConnectionFactory;
importjavax.jms.Destination;
importjavax.jms.MessageProducer;
importjavax.jms.Session;
importjavax.jms.TextMessage;
importorg.apache.activemq.ActiveMQConnectionFactory;
publicclassJMSPublisher{
publicstaticvoidmain(String[]args)throwsException{
//創(chuàng)建連接工廠
ConnectionFactoryconnectionFactory=newActiveMQConnectionFactory("tcp://localhost:61616");
//創(chuàng)建連接
Connectionconnection=connectionFactory.createConnection();
//啟動(dòng)連接
connection.start();
//創(chuàng)建會(huì)話
Sessionsession=connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//創(chuàng)建主題
Destinationdestination=session.createTopic("MyTopic");
//創(chuàng)建消息生產(chǎn)者
MessageProducerproducer=session.createProducer(destination);
//創(chuàng)建消息
TextMessagemessage=session.createTextMessage("Hello,ActiveMQ!");
//發(fā)送消息
producer.send(message);
//關(guān)閉資源
producer.close();
session.close();
connection.close();
}
}訂閱消息importjavax.jms.Connection;
importjavax.jms.ConnectionFactory;
importjavax.jms.Destination;
importjavax.jms.Message;
importjavax.jms.MessageConsumer;
importjavax.jms.Session;
importjavax.jms.TextMessage;
importorg.apache.activemq.ActiveMQConnectionFactory;
publicclassJMSSubscriber{
publicstaticvoidmain(String[]args)throwsException{
//創(chuàng)建連接工廠
ConnectionFactoryconnectionFactory=newActiveMQConnectionFactory("tcp://localhost:61616");
//創(chuàng)建連接
Connectionconnection=connectionFactory.createConnection();
//啟動(dòng)連接
connection.start();
//創(chuàng)建會(huì)話
Sessionsession=connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//創(chuàng)建主題
Destinationdestination=session.createTopic("MyTopic");
//創(chuàng)建消息消費(fèi)者
MessageConsumerconsumer=session.createConsumer(destination);
//接收消息
Messagemessage=consumer.receive();
//檢查消息類(lèi)型
if(messageinstanceofTextMessage){
TextMessagetextMessage=(TextMessage)message;
//打印消息內(nèi)容
System.out.println("Receivedmessage:"+textMessage.getText());
}
//關(guān)閉資源
consumer.close();
session.close();
connection.close();
}
}在這個(gè)示例中,我們首先創(chuàng)建了一個(gè)連接工廠,然后使用這個(gè)工廠創(chuàng)建了一個(gè)連接。我們創(chuàng)建了一個(gè)會(huì)話,然后使用會(huì)話創(chuàng)建了一個(gè)主題。發(fā)布者使用會(huì)話創(chuàng)建了一個(gè)消息,并將其發(fā)送到主題。訂閱者從主題中接收消息并處理。如果多個(gè)訂閱者訂閱了同一個(gè)主題,每個(gè)訂閱者都會(huì)接收到每條消息的副本。2點(diǎn)對(duì)點(diǎn)消息模式2.1點(diǎn)對(duì)點(diǎn)模式定義點(diǎn)對(duì)點(diǎn)(Point-to-Point,P2P)消息模式是消息隊(duì)列中的一種基本通信模式。在這種模式下,消息被發(fā)送到一個(gè)隊(duì)列中,然后由一個(gè)或多個(gè)消費(fèi)者接收。但是,一旦消息被一個(gè)消費(fèi)者接收,它就會(huì)從隊(duì)列中移除,確保消息只被處理一次。這種模式非常適合于需要確保消息被準(zhǔn)確處理一次的場(chǎng)景。2.2點(diǎn)對(duì)點(diǎn)模式下的消息傳遞過(guò)程在點(diǎn)對(duì)點(diǎn)模式中,消息的傳遞過(guò)程遵循以下步驟:消息生產(chǎn)者(Producer)創(chuàng)建消息并將其發(fā)送到消息隊(duì)列中。消息隊(duì)列(Queue)存儲(chǔ)消息,直到被消費(fèi)者接收。消息消費(fèi)者(Consumer)從隊(duì)列中拉取消息并處理。消息確認(rèn):消費(fèi)者處理完消息后,向隊(duì)列發(fā)送確認(rèn),隊(duì)列隨后刪除該消息。2.2.1示例代碼:使用ActiveMQ實(shí)現(xiàn)點(diǎn)對(duì)點(diǎn)消息模式importorg.apache.activemq.ActiveMQConnectionFactory;
importjavax.jms.*;
publicclassJMSProducer{
publicstaticvoidmain(String[]args){
ConnectionFactoryconnectionFactory=newActiveMQConnectionFactory("tcp://localhost:61616");
try(Connectionconnection=connectionFactory.createConnection()){
connection.start();
Sessionsession=connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
Queuequeue=session.createQueue("P2PQueue");
MessageProducerproducer=session.createProducer(queue);
TextMessagemessage=session.createTextMessage("Hello,P2PQueue!");
producer.send(message);
System.out.println("Sentmessage:"+message.getText());
}catch(JMSExceptione){
e.printStackTrace();
}
}
}importorg.apache.activemq.ActiveMQConnectionFactory;
importjavax.jms.*;
publicclassJMSConsumer{
publicstaticvoidmain(String[]args){
ConnectionFactoryconnectionFactory=newActiveMQConnectionFactory("tcp://localhost:61616");
try(Connectionconnection=connectionFactory.createConnection()){
connection.start();
Sessionsession=connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
Queuequeue=session.createQueue("P2PQueue");
MessageConsumerconsumer=session.createConsumer(queue);
TextMessagemessage=(TextMessage)consumer.receive();
System.out.println("Receivedmessage:"+message.getText());
//消息被接收后,自動(dòng)從隊(duì)列中移除
}catch(JMSExceptione){
e.printStackTrace();
}
}
}2.2.2代碼解釋JMSProducer:這段代碼創(chuàng)建了一個(gè)ActiveMQ的連接,并通過(guò)createProducer方法創(chuàng)建了一個(gè)消息生產(chǎn)者。然后,它創(chuàng)建了一個(gè)文本消息并將其發(fā)送到名為P2PQueue的隊(duì)列中。JMSConsumer:消費(fèi)者代碼也創(chuàng)建了一個(gè)ActiveMQ的連接,然后通過(guò)createConsumer方法創(chuàng)建了一個(gè)消息消費(fèi)者。消費(fèi)者從隊(duì)列中接收消息并打印出來(lái),由于使用了AUTO_ACKNOWLEDGE,消息在被接收后會(huì)自動(dòng)從隊(duì)列中移除。2.3點(diǎn)對(duì)點(diǎn)模式的特點(diǎn)與優(yōu)勢(shì)點(diǎn)對(duì)點(diǎn)模式具有以下特點(diǎn)和優(yōu)勢(shì):消息的獨(dú)占性:一旦消息被一個(gè)消費(fèi)者接收,它就不會(huì)再被其他消費(fèi)者接收,確保了消息的獨(dú)占處理??煽啃裕和ㄟ^(guò)消息確認(rèn)機(jī)制,可以確保消息被成功處理。如果消費(fèi)者未能處理消息或崩潰,消息可以被重新發(fā)送。靈活性:消費(fèi)者可以是動(dòng)態(tài)的,即消費(fèi)者可以在消息被發(fā)送后加入或離開(kāi),而不會(huì)影響消息的傳遞。負(fù)載均衡:在多個(gè)消費(fèi)者訂閱同一隊(duì)列時(shí),消息會(huì)被均衡地分發(fā)給不同的消費(fèi)者,提高了系統(tǒng)的處理能力。點(diǎn)對(duì)點(diǎn)模式非常適合于需要處理大量消息且每個(gè)消息需要被準(zhǔn)確處理一次的場(chǎng)景,如訂單處理、事務(wù)處理等。通過(guò)使用ActiveMQ,可以輕松地在Java應(yīng)用程序中實(shí)現(xiàn)這種模式,提高系統(tǒng)的可靠性和效率。3發(fā)布訂閱消息模式3.1發(fā)布訂閱模式定義發(fā)布訂閱模式(Publish-Subscribe,簡(jiǎn)稱(chēng)Pub/Sub)是一種消息傳遞模式,其中消息的發(fā)送者(發(fā)布者)不會(huì)將消息直接發(fā)送給特定的接收者(訂閱者)。相反,發(fā)布者將消息發(fā)布到一個(gè)特定的主題或頻道上,而訂閱者則訂閱這些主題或頻道以接收消息。這種模式允許一個(gè)發(fā)布者向多個(gè)訂閱者發(fā)送消息,而訂閱者可以接收來(lái)自多個(gè)發(fā)布者的消息。3.2發(fā)布訂閱模式下的消息傳遞過(guò)程3.2.1發(fā)布者操作創(chuàng)建一個(gè)與特定主題或頻道關(guān)聯(lián)的發(fā)布者。發(fā)布者將消息發(fā)送到該主題或頻道,消息中可能包含數(shù)據(jù)、事件或通知。3.2.2訂閱者操作創(chuàng)建一個(gè)訂閱者,訂閱感興趣的特定主題或頻道。訂閱者監(jiān)聽(tīng)這些主題或頻道,一旦有消息發(fā)布,訂閱者就會(huì)接收到消息。訂閱者處理接收到的消息,執(zhí)行相應(yīng)的邏輯或操作。3.2.3中間件操作中間件(如ActiveMQ)接收來(lái)自發(fā)布者的消息,并將這些消息存儲(chǔ)在相應(yīng)的主題或頻道中。當(dāng)訂閱者連接并訂閱主題或頻道時(shí),中間件會(huì)將存儲(chǔ)的消息推送給訂閱者。中間件確保消息的傳遞,即使在發(fā)布者和訂閱者之間沒(méi)有直接的連接。3.2.4示例代碼importorg.apache.activemq.ActiveMQConnectionFactory;
//創(chuàng)建連接工廠
ActiveMQConnectionFactoryconnectionFactory=newActiveMQConnectionFactory("tcp://localhost:61616");
//創(chuàng)建連接
Connectionconnection=connectionFactory.createConnection();
//啟動(dòng)連接
connection.start();
//創(chuàng)建會(huì)話
Sessionsession=connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//創(chuàng)建主題
Topictopic=session.createTopic("MyTopic");
//創(chuàng)建消息生產(chǎn)者
MessageProducerproducer=session.createProducer(topic);
//創(chuàng)建文本消息
TextMessagemessage=session.createTextMessage("Hello,Pub/Sub!");
//發(fā)送消息
producer.send(message);
//關(guān)閉資源
session.close();
connection.close();importorg.apache.activemq.ActiveMQConnectionFactory;
//創(chuàng)建連接工廠
ActiveMQConnectionFactoryconnectionFactory=newActiveMQConnectionFactory("tcp://localhost:61616");
//創(chuàng)建連接
Connectionconnection=connectionFactory.createConnection();
//啟動(dòng)連接
connection.start();
//創(chuàng)建會(huì)話
Sessionsession=connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//創(chuàng)建主題
Topictopic=session.createTopic("MyTopic");
//創(chuàng)建消息消費(fèi)者
MessageConsumerconsumer=session.createConsumer(topic);
//接收消息
TextMessagemessage=(TextMessage)consumer.receive();
//處理消息
if(message!=null){
System.out.println("Receivedmessage:"+message.getText());
}
//關(guān)閉資源
session.close();
connection.close();3.3發(fā)布訂閱模式的特點(diǎn)與優(yōu)勢(shì)3.3.1特點(diǎn)多對(duì)多通信:一個(gè)發(fā)布者可以向多個(gè)訂閱者發(fā)送消息,同時(shí)一個(gè)訂閱者可以接收來(lái)自多個(gè)發(fā)布者的消息。解耦:發(fā)布者和訂閱者之間沒(méi)有直接的依賴(lài),它們只需要知道主題或頻道的名稱(chēng)。異步通信:消息的發(fā)送和接收是異步的,訂閱者可以在任何時(shí)間接收消息,即使在消息發(fā)布時(shí)訂閱者不在線。3.3.2優(yōu)勢(shì)靈活性:系統(tǒng)可以輕松地添加新的發(fā)布者或訂閱者,而無(wú)需修改現(xiàn)有的代碼??蓴U(kuò)展性:可以輕松地?cái)U(kuò)展系統(tǒng)以處理更多的消息或更多的訂閱者??煽啃裕褐虚g件可以確保消息的傳遞,即使在發(fā)布者和訂閱者之間沒(méi)有直接的連接。通過(guò)上述代碼示例和解釋?zhuān)覀兛梢钥吹桨l(fā)布訂閱模式在ActiveMQ中的實(shí)現(xiàn)方式,以及它如何提供一種靈活、可擴(kuò)展和可靠的消息傳遞機(jī)制。4ActiveMQ中的點(diǎn)對(duì)點(diǎn)與發(fā)布訂閱4.1在ActiveMQ中實(shí)現(xiàn)點(diǎn)對(duì)點(diǎn)模式點(diǎn)對(duì)點(diǎn)(Point-to-Point,P2P)模式是消息隊(duì)列中的一種通信模式,其中消息被發(fā)送到隊(duì)列,然后由一個(gè)或多個(gè)消費(fèi)者接收。一旦消息被某個(gè)消費(fèi)者接收,它就會(huì)從隊(duì)列中移除,確保每個(gè)消息只被處理一次。4.1.1原理在P2P模式下,ActiveMQ創(chuàng)建一個(gè)隊(duì)列,生產(chǎn)者將消息發(fā)送到該隊(duì)列。消費(fèi)者訂閱隊(duì)列,接收并處理消息。如果多個(gè)消費(fèi)者訂閱同一個(gè)隊(duì)列,消息將被分發(fā)給其中一個(gè)消費(fèi)者,而不是所有消費(fèi)者。4.1.2配置與管理要配置ActiveMQ以使用P2P模式,需要在創(chuàng)建隊(duì)列時(shí)指定隊(duì)列類(lèi)型。例如,使用Queue類(lèi)型創(chuàng)建隊(duì)列。管理方面,可以通過(guò)ActiveMQ的Web控制臺(tái)或使用JMX(JavaManagementExtensions)來(lái)監(jiān)控隊(duì)列的狀態(tài)和消息的流動(dòng)。4.1.3代碼示例下面是一個(gè)使用Java和ActiveMQ實(shí)現(xiàn)點(diǎn)對(duì)點(diǎn)模式的示例代碼:importjavax.jms.Connection;
importjavax.jms.ConnectionFactory;
importjavax.jms.Destination;
importjavax.jms.MessageConsumer;
importjavax.jms.MessageProducer;
importjavax.jms.Session;
importjavax.jms.TextMessage;
importorg.apache.activemq.ActiveMQConnectionFactory;
publicclassP2PExample{
publicstaticvoidmain(String[]args)throwsException{
//創(chuàng)建連接工廠
ConnectionFactoryconnectionFactory=newActiveMQConnectionFactory("tcp://localhost:61616");
//創(chuàng)建連接
Connectionconnection=connectionFactory.createConnection();
//啟動(dòng)連接
connection.start();
//創(chuàng)建會(huì)話
Sessionsession=connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//創(chuàng)建隊(duì)列
Destinationdestination=session.createQueue("P2PQueue");
//生產(chǎn)者
MessageProducerproducer=session.createProducer(destination);
TextMessagemessage=session.createTextMessage("Hello,P2P!");
producer.send(message);
System.out.println("Sentmessage:"+message.getText());
//消費(fèi)者
MessageConsumerconsumer=session.createConsumer(destination);
TextMessagereceivedMessage=(TextMessage)consumer.receive();
System.out.println("Receivedmessage:"+receivedMessage.getText());
//關(guān)閉資源
consumer.close();
producer.close();
session.close();
connection.close();
}
}在這個(gè)例子中,我們創(chuàng)建了一個(gè)名為P2PQueue的隊(duì)列,并通過(guò)生產(chǎn)者發(fā)送了一條消息。然后,一個(gè)消費(fèi)者接收并處理了這條消息。由于是點(diǎn)對(duì)點(diǎn)模式,如果此時(shí)有多個(gè)消費(fèi)者訂閱,消息只會(huì)被其中一個(gè)消費(fèi)者接收。4.2在ActiveMQ中實(shí)現(xiàn)發(fā)布訂閱模式發(fā)布訂閱(Publish-Subscribe,Pub/Sub)模式是另一種消息通信模式,其中消息被發(fā)布到一個(gè)主題,所有訂閱該主題的消費(fèi)者都會(huì)接收到消息的副本。這種模式適用于需要將消息廣播給多個(gè)接收者的情況。4.2.1原理在Pub/Sub模式下,ActiveMQ創(chuàng)建一個(gè)主題,生產(chǎn)者將消息發(fā)布到該主題。消費(fèi)者訂閱主題,接收并處理消息。與P2P模式不同,每個(gè)訂閱者都會(huì)接收到消息的完整副本,即使有多個(gè)訂閱者同時(shí)在線。4.2.2配置與管理配置ActiveMQ使用Pub/Sub模式,需要在創(chuàng)建主題時(shí)指定主題類(lèi)型。例如,使用Topic類(lèi)型創(chuàng)建主題。管理方面,同樣可以通過(guò)ActiveMQ的Web控制臺(tái)或JMX來(lái)監(jiān)控主題的狀態(tài)和消息的流動(dòng)。4.2.3代碼示例下面是一個(gè)使用Java和ActiveMQ實(shí)現(xiàn)發(fā)布訂閱模式的示例代碼:importjavax.jms.Connection;
importjavax.jms.ConnectionFactory;
importjavax.jms.Destination;
importjavax.jms.MessageConsumer;
importjavax.jms.MessageProducer;
importjavax.jms.Session;
importjavax.jms.TextMessage;
importorg.apache.activemq.ActiveMQConnectionFactory;
publicclassPubSubExample{
publicstaticvoidmain(String[]args)throwsException{
//創(chuàng)建連接工廠
ConnectionFactoryconnectionFactory=newActiveMQConnectionFactory("tcp://localhost:61616");
//創(chuàng)建連接
Connectionconnection=connectionFactory.createConnection();
//啟動(dòng)連接
connection.start();
//創(chuàng)建會(huì)話
Sessionsession=connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//創(chuàng)建主題
Destinationdestination=session.createTopic("PubSubTopic");
//生產(chǎn)者
MessageProducerproducer=session.createProducer(destination);
TextMessagemessage=session.createTextMessage("Hello,Pub/Sub!");
producer.send(message);
System.out.println("Sentmessage:"+message.getText());
//消費(fèi)者1
MessageConsumerconsumer1=session.createConsumer(destination);
TextMessagereceivedMessage1=(TextMessage)consumer1.receive();
System.out.println("Consumer1receivedmessage:"+receivedMessage1.getText());
//消費(fèi)者2
MessageConsumerconsumer2=session.createConsumer(destination);
TextMessagereceivedMessage2=(TextMessage)consumer2.receive();
System.out.println("Consumer2receivedmessage:"+receivedMessage2.getText());
//關(guān)閉資源
consumer1.close();
consumer2.close();
producer.close();
session.close();
connection.close();
}
}在這個(gè)例子中,我們創(chuàng)建了一個(gè)名為PubSubTopic的主題,并通過(guò)生產(chǎn)者發(fā)送了一條消息。然后,兩個(gè)消費(fèi)者訂閱了該主題,并各自接收到消息的副本。這展示了Pub/Sub模式下消息的廣播特性。4.3點(diǎn)對(duì)點(diǎn)與發(fā)布訂閱模式的配置與管理配置和管理ActiveMQ中的點(diǎn)對(duì)點(diǎn)和發(fā)布訂閱模式,主要涉及以下方面:隊(duì)列和主題的創(chuàng)建:通過(guò)createQueue和createTopic方法創(chuàng)建。生產(chǎn)者和消費(fèi)者的創(chuàng)建:使用會(huì)話的createProducer和createConsumer方法,分別指定隊(duì)列或主題作為目標(biāo)。消息的發(fā)送和接收:生產(chǎn)者使用send方法發(fā)送消息,消費(fèi)者使用receive方法接收消息。監(jiān)控和管理:通過(guò)ActiveMQ的Web控制臺(tái)或JMX接口,可以查看隊(duì)列和主題的狀態(tài),包括消息數(shù)量、消費(fèi)者和生產(chǎn)者列表等。在實(shí)際應(yīng)用中,根據(jù)業(yè)務(wù)需求選擇合適的模式非常重要。點(diǎn)對(duì)點(diǎn)模式適用于消息需要被處理一次且僅一次的場(chǎng)景,而發(fā)布訂閱模式適用于消息需要被多個(gè)消費(fèi)者同時(shí)處理的場(chǎng)景。5點(diǎn)對(duì)點(diǎn)與發(fā)布訂閱模式的對(duì)比5.1消息傳遞機(jī)制的差異5.1.1點(diǎn)對(duì)點(diǎn)(Point-to-Point,P2P)在點(diǎn)對(duì)點(diǎn)模式中,消息被發(fā)送到一個(gè)隊(duì)列中,每個(gè)消息都有一個(gè)消費(fèi)者。一旦消息被消費(fèi),它就會(huì)從隊(duì)列中移除。這種模式確保了消息的單次消費(fèi),適用于需要處理一次且僅一次消息的場(chǎng)景。示例代碼importorg.apache.activemq.ActiveMQConnectionFactory;
//創(chuàng)建連接工廠
ActiveMQConnectionFactoryconnectionFactory=newActiveMQConnectionFactory("tcp://localhost:61616");
//創(chuàng)建連接
Connectionconnection=connectionFactory.createConnection();
//啟動(dòng)連接
connection.start();
//創(chuàng)建會(huì)話
Sessionsession=connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//創(chuàng)建隊(duì)列
Destinationdestination=session.createQueue("P2PQueue");
//創(chuàng)建消息生產(chǎn)者
MessageProducerproducer=session.createProducer(destination);
//創(chuàng)建消息
TextMessagemessage=session.createTextMessage("Hello,P2P!");
//發(fā)送消息
producer.send(message);
//關(guān)閉資源
producer.close();
session.close();
connection.close();在上述代碼中,我們創(chuàng)建了一個(gè)ActiveMQ的點(diǎn)對(duì)點(diǎn)隊(duì)列P2PQueue,并通過(guò)MessageProducer發(fā)送了一條消息Hello,P2P!。消息將被隊(duì)列中的一個(gè)消費(fèi)者消費(fèi)。5.1.2發(fā)布訂閱(Publish-Subscribe,Pub/Sub)發(fā)布訂閱模式中,消息被發(fā)送到一個(gè)主題,所有訂閱該主題的消費(fèi)者都會(huì)收到消息的副本。這種模式適用于需要將消息廣播給多個(gè)訂閱者的情況,例如實(shí)時(shí)新聞更新或股票價(jià)格更新。示例代碼importorg.apache.activemq.ActiveMQConnectionFactory;
//創(chuàng)建連接工廠
ActiveMQConnectionFactoryconnectionFactory=newActiveMQConnectionFactory("tcp://localhost:61616");
//創(chuàng)建連接
Connectionconnection=connectionFactory.createConnection();
//啟動(dòng)連接
connection.start();
//創(chuàng)建會(huì)話
Sessionsession=connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//創(chuàng)建主題
Destinationdestination=session.createTopic("PubSubTopic");
//創(chuàng)建消息生產(chǎn)者
MessageProducerproducer=session.createProducer(destination);
//創(chuàng)建消息
TextMessagemessage=session.createTextMessage("Hello,Pub/Sub!");
//發(fā)送消息
producer.send(message);
//關(guān)閉資源
producer.close();
session.close();
connection.close();在發(fā)布訂閱模式下,我們創(chuàng)建了一個(gè)主題PubSubTopic,并通過(guò)MessageProducer發(fā)送了一條消息Hello,Pub/Sub!。所有訂閱該主題的消費(fèi)者都將收到這條消息的副本。5.2應(yīng)用場(chǎng)景的對(duì)比5.2.1點(diǎn)對(duì)點(diǎn)模式訂單處理:當(dāng)一個(gè)訂單被提交后,它被發(fā)送到一個(gè)隊(duì)列中,由一個(gè)訂單處理服務(wù)消費(fèi)并處理。由于訂單需要被準(zhǔn)確處理一次,點(diǎn)對(duì)點(diǎn)模式是理想的選擇。文件上傳:用戶(hù)上傳的文件被放入隊(duì)列,由文件處理服務(wù)消費(fèi)并存儲(chǔ)。確保文件被處理一次且僅一次。5.2.2發(fā)布訂閱模式實(shí)時(shí)新聞更新:新聞服務(wù)器將最新的新聞更新發(fā)布到一個(gè)主題,所有訂閱該主題的客戶(hù)端都會(huì)收到更新。股票價(jià)格更新:股票價(jià)格變動(dòng)被發(fā)布到一個(gè)主題,所有訂閱該主題的交易者都會(huì)收到最新的價(jià)格信息。5.3性能與可靠性考量5.3.1點(diǎn)對(duì)點(diǎn)模式性能:由于消息被消費(fèi)后即被移除,點(diǎn)對(duì)點(diǎn)模式在處理大量消息時(shí)可能比發(fā)布訂閱模式更高效。可靠性:確保消息被處理一次且僅一次,適用于對(duì)消息處理準(zhǔn)確性要求高的場(chǎng)景。5.3.2發(fā)布訂閱模式性能:發(fā)布訂閱模式在消息廣播給多個(gè)消費(fèi)者時(shí)可能消耗更多資源,尤其是在消費(fèi)者數(shù)量龐大時(shí)??煽啃裕合⒈粡V播給所有訂閱者,確保了消息的廣泛傳播,但可能需要額外的機(jī)制來(lái)確保消息的準(zhǔn)確處理,例如消息確認(rèn)機(jī)制。通過(guò)對(duì)比點(diǎn)對(duì)點(diǎn)與發(fā)布訂閱模式,我們可以根據(jù)具體的應(yīng)用需求和場(chǎng)景選擇最合適的ActiveMQ消息類(lèi)型,以實(shí)現(xiàn)高效、可靠的消息傳遞。6實(shí)踐案例與最佳實(shí)踐6.1點(diǎn)對(duì)點(diǎn)模式的實(shí)踐案例在點(diǎn)對(duì)點(diǎn)(Point-to-Point,P2P)模式中,消息被發(fā)送到隊(duì)列,每個(gè)消費(fèi)者獨(dú)立地從隊(duì)列中拉取消息。一旦消息被某個(gè)消費(fèi)者處理,它將從隊(duì)列中移除,確保消息只被處理一次。下面是一個(gè)使用Java和ActiveMQ實(shí)現(xiàn)點(diǎn)對(duì)點(diǎn)模式的示例。6.1.1示例代碼importorg.apache.activemq.ActiveMQConnectionFactory;
importjavax.jms.*;
publicclassP2PExample{
privatestaticfinalStringBROKER_URL="tcp://localhost:61616";
privatestaticfinalStringQUEUE_NAME="P2P_Queue";
publicstaticvoidmain(String[]args)throwsJMSException{
//創(chuàng)建連接工廠
ConnectionFactoryconnectionFactory=newActiveMQConnectionFactory(BROKER_URL);
//創(chuàng)建連接
Connectionconnection=connectionFactory.createConnection();
connection.start();
//創(chuàng)建會(huì)話
Sessionsession=connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//創(chuàng)建隊(duì)列
Queuequeue=session.createQueue(QUEUE_NAME);
//創(chuàng)建消息生產(chǎn)者
MessageProducerproducer=session.createProducer(queue);
//創(chuàng)建消息消費(fèi)者
MessageConsumerconsumer1=session.createConsumer(queue);
MessageConsumerconsumer2=session.createConsumer(queue);
//發(fā)送消息
TextMessagemessage=session.createTextMessage("Hello,P2PQueue!");
producer.send(message);
System.out.println("MessagesenttoP2PQueue");
//消費(fèi)者1接收消息
TextMessagereceivedMessage1=(TextMessage)consumer1.receive();
System.out.println("Consumer1received:"+receivedMessage1.getText());
//消費(fèi)者2嘗試接收消息,但消息已被消費(fèi)者1處理
TextMessagereceivedMessage2=(TextMessage)consumer2.receive(1000);
if(receivedMessage2==null){
System.out.println("Consumer2didnotreceiveanymessage");
}
//關(guān)閉資源
consumer1.close();
consumer2.close();
session.close();
connection.close();
}
}6.1.2代碼解釋連接創(chuàng)建:使用ActiveMQConnectionFactory創(chuàng)建連接到ActiveMQ的Connection。會(huì)話創(chuàng)建:通過(guò)Connection創(chuàng)建Session,設(shè)置為自動(dòng)確認(rèn)模式。隊(duì)列創(chuàng)建:使用Session創(chuàng)建一個(gè)隊(duì)列P2P_Queue。消息生產(chǎn)者與消費(fèi)者創(chuàng)建:創(chuàng)建MessageProducer用于發(fā)送消息,創(chuàng)建兩個(gè)MessageConsumer用于接收消息。消息發(fā)送與接收:生產(chǎn)者發(fā)送一條文本消息到隊(duì)列,消費(fèi)者1成功接收并處理消息,消費(fèi)者2嘗試接收但未成功,因?yàn)橄⒁驯幌M(fèi)者1處理。資源關(guān)閉:確保所有資源在使用后被關(guān)閉,避免資源泄露。6.2發(fā)布訂閱模式的實(shí)踐案例發(fā)布訂閱(Publish-Subscribe,Pub/Sub)模式中,消息被廣播到所有訂閱者,每個(gè)訂閱者都會(huì)接收到消息的副本。下面是一個(gè)使用Java和ActiveMQ實(shí)現(xiàn)發(fā)布訂閱模式的示例。6.2.1示例代碼importorg.apache.activemq.ActiveMQConnectionF
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024藝術(shù)學(xué)校教室租賃與藝術(shù)展覽合作合同3篇
- 二零二五年度風(fēng)力發(fā)電設(shè)備安裝與運(yùn)營(yíng)合同3篇
- 2025年度貓咪品種引進(jìn)與銷(xiāo)售代理合同4篇
- 二零二四年光伏發(fā)電項(xiàng)目爆破鉆孔合同
- 南昌市2025年度新建住宅買(mǎi)賣(mài)合同
- 二零二五版環(huán)保設(shè)施建設(shè)與運(yùn)營(yíng)合同3篇
- 2025年度餐飲企業(yè)知識(shí)產(chǎn)權(quán)保護(hù)合同18篇
- 年度超高純氣體的純化設(shè)備戰(zhàn)略市場(chǎng)規(guī)劃報(bào)告
- 2025版智能交通信號(hào)系統(tǒng)零星維修施工合同4篇
- 二零二五年度車(chē)輛抵押擔(dān)保信托合同范本3篇
- 稱(chēng)量與天平培訓(xùn)試題及答案
- 超全的超濾與納濾概述、基本理論和應(yīng)用
- 2020年醫(yī)師定期考核試題與答案(公衛(wèi)專(zhuān)業(yè))
- 2022年中國(guó)育齡女性生殖健康研究報(bào)告
- 各種靜脈置管固定方法
- 消防報(bào)審驗(yàn)收程序及表格
- 教育金規(guī)劃ppt課件
- 呼吸機(jī)波形分析及臨床應(yīng)用
- 常用緊固件選用指南
- 私人借款協(xié)議書(shū)新編整理版示范文本
- 自薦書(shū)(彩色封面)
評(píng)論
0/150
提交評(píng)論