<blockquote><h4>認識消息隊列</h4></blockquote>
“消息”是在兩臺計算機間傳送的數據單位。消息可以非常簡單,例如只包含文本字符串;也可以更復雜,可能包含對象……
消息被發送到隊列中。“消息隊列”是在消息的傳輸過程中保存消息的容器。消息隊列管理器在將消息從它的源中繼到它的目標時充當中間人。隊列的主要目的是提供路由并保證消息的傳遞;如果發送消息時接收者不可用,消息隊列會保留消息,直到可以成功地傳遞它。
<blockquote><h4>JMS消息隊列</h4></blockquote>
Jms即[Java消息服務](http://baike.baidu.com/view/3292569.htm)(Java Message Service)[應用程序](http://baike.baidu.com/view/330120.htm)接口是一個[Java平臺](http://baike.baidu.com/view/209634.htm)中關于面向[消息中間件](http://baike.baidu.com/view/3118541.htm)(MOM)的API,用于在兩個應用程序之間,或[分布式系統](http://baike.baidu.com/view/991489.htm)中發送消息,進行異步通信。Java消息服務是一個與具體平臺無關的API,絕大多數MOM提供[商都](http://baike.baidu.com/view/19763.htm)對JMS提供支持。
JMS(Java Messaging Service)是[Java](http://baike.baidu.com/view/29.htm)平臺上有關面向消息中間件(MOM)的技術規范,它便于消息系統中的Java[應用程序](http://baike.baidu.com/view/330120.htm)進行消息交換,并且通過提供標準的產生、發送、接收消息的接口簡化[企業](http://baike.baidu.com/view/38340.htm)應用的開發,翻譯為[Java](http://baike.baidu.com/view/29.htm)消息[服務](http://baike.baidu.com/view/133203.htm)。
<blockquote><h4>JMS對象模型</h4></blockquote>
1)連接工廠。連接工廠(ConnectionFactory)是由管理員創建,并綁定到JNDI樹中。客戶端使用JNDI查找連接工廠,然后利用連接工廠創建一個JMS連接。
2)JMS連接。JMS連接(Connection)表示JMS客戶端和服務器端之間的一個活動的連接,是由客戶端通過調用連接工廠的方法建立的。
3)JMS會話。JMS會話(Session)表示JMS客戶與JMS服務器之間的會話狀態。JMS會話建立在JMS連接上,表示客戶與服務器之間的一個會話線程。
4)JMS目的。JMS目的(Destination),又稱為消息隊列,是實際的消息源。
5)JMS生產者和消費者。生產者(Message Producer)和消費者(Message Consumer)對象由Session對象創建,用于發送和接收消息。
6)JMS消息通常有兩種類型: ① 點對點(Point-to-Point)。在點對點的消息系統中,消息分發給一個單獨的使用者。點對點消息往往與隊列(javax.jms.Queue)相關聯。 ② 發布/訂閱(Publish/Subscribe)。發布/訂閱消息系統支持一個事件驅動模型,消息生產者和消費者都參與消息的傳遞。生產者發布事件,而使用者訂閱感興趣的事件,并使用事件。該類型消息一般與特定的主題(javax.jms.Topic)關聯。
<blockquote><h4>ActiveMQ代碼實現</h4></blockquote>
1)下載ActiveMQ
去官方網站下載:http://activemq.apache.org/
2)解壓運行AciveMQ
解壓apache-activemq-5.13.3-bin.zip文件,運行apache-activemq-5.13.3\bin\win64\activemq.bat,啟動ActiveMQ,登錄http://localhost:8161/admin/,創建一個Queues,命名為my-activemq
3)創建Maven項目,添加依賴POM.xml
dependencies>
<!-- activemq 相關maven依賴 -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.7.0</version>
</dependency>
<!-- 日志相關依賴 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
4)創建消息發送者(生產者)Sender.java
package com.zxp.activemq;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 發送者
* 2016年5月6日 下午3:00:57
* @author zhangxiaoping
*/
public class Sender {
private static final Logger LOGGER=LoggerFactory.getLogger(Sender.class);
//默認代理地址 "failover://tcp://localhost:61616" 服務器地址不同IP修改不同的IP
private static final String BROKER_URL=ActiveMQConnection.DEFAULT_BROKER_URL;
//消息隊列名稱
private static final String SUBJECT="my-activemq";
private static int i=1;
public static void main(String[] args) throws JMSException, InterruptedException {
//初始化連接工廠
ConnectionFactory connectionFactory=new ActiveMQConnectionFactory(BROKER_URL);
//建立連接
Connection conn= connectionFactory.createConnection();
//啟動連接
conn.start();
//創建Session,此方法第一個參數表示會話是否在事務中執行,第二個參數設定會話的應答模式
Session session= conn.createSession(false,Session.AUTO_ACKNOWLEDGE);
//創建目標隊列
Destination dest = session.createQueue(SUBJECT);
//通過session創建消息的發送者
MessageProducer producer=session.createProducer(dest);
while(true){
//定義要發送的消息
TextMessage message= session.createTextMessage("======ActiveMQ發送消息===="+i+"===");
LOGGER.debug(message.getText());
//發送消息
producer.send(message);
//休眠2秒
Thread.sleep(2000);
i++;
}
// conn.close();
}
}
5)創建消息的接收者(消費者)Receiver.java
package com.zxp.activemq;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 接收者
* 2016年5月6日 下午3:03:16
* @author zhangxiaoping
*/
public class Receiver implements MessageListener{
private static final Logger LOGGER=LoggerFactory.getLogger(Receiver.class);
//默認代理地址 "failover://tcp://localhost:61616" 服務器地址不同IP修改不同的IP
private static final String BROKER_URL=ActiveMQConnection.DEFAULT_BROKER_URL;
//消息隊列名稱
private static final String SUBJECT="my-activemq";
public static void main(String[] args) throws JMSException {
//初始化連接工廠
ConnectionFactory connectionFactory=new ActiveMQConnectionFactory(BROKER_URL);
//建立連接
Connection conn= connectionFactory.createConnection();
//啟動連接
conn.start();
//創建Session,此方法第一個參數表示會話是否在事務中執行,第二個參數設定會話的應答模式
Session session= conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
//創建目標隊列
Destination dest=session.createQueue(SUBJECT);
//通過session創建消息的接收者
MessageConsumer consumer= session.createConsumer(dest);
//初始化監聽
Receiver receiver=new Receiver();
//給接收者添加監聽對象
consumer.setMessageListener(receiver);
}
public void onMessage(Message arg0) {
TextMessage message=(TextMessage) arg0;
try {
LOGGER.debug("接收到消息"+message.getText());
Thread.sleep(4000);
} catch (Exception e) {
LOGGER.error("error"+e.getMessage());
}
}
}
6)運行Sender.java、Receiver.java登錄http://localhost:8161/admin/查看隊列信息。