一、什麼是ActiveMQ
AciveMQ是Apache出品的目前最流行,能力強勁的開源消息總線
消息列隊有兩種消息模式,一種是點對點的消息模式,還有一種就是訂閱的模式.
主要功能:
- 解決服務器之間的耦合性
- 使用消息隊列,增加系統併發處理量
主要應用場景:
- 當系統使用短信平臺、郵件平臺的時候
- 當系統使用搜索平臺、緩存平臺的時候你
二、使用外置ActiveMQ流程:
1.官網地址:http://activemq.apache.org/
2.安裝包下載完成後解壓後 就是這個樣子了 (注意一定要解壓到全英文路徑下的包內)
4.雙擊啓動activemq.bat
5.點完之後會自動彈出來doc啓動,稍等一下 如果你最後跟我的一樣 說明啓動成功了
6.啓動成功,在瀏覽器中訪問http://localhost:8161/ 就能訪問到activemq的頁面
7.登錄成功後(用戶名和密碼都是admin),會有兩個隊列:topic和queue (後臺創建隊列,這邊會實時顯示)
三、兩種消息模式
1.點對點的實現代碼
項目使用MAVEN來構建(pom.xml)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itsiji</groupId>
<artifactId>activemq</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!--activemq-->
<dependencies>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-client</artifactId>
<version>5.13.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- java編譯插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
1.1點對點的發送方
需要注意的:連接地址的ip和端口號是 127.0.0.1:61616
在頁面管理控制檯查看消息隊列的ip和端口號是 127.0.0.1:8161
package com.itsiji.test.queue;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
public class TestQueueSend {
//連接賬號
private String userName = "";
//連接密碼
private String password = "";
//連接地址
private String brokerURL = "tcp://127.0.0.1:61616";
//connection的工廠
private ConnectionFactory factory;
//連接對象
private Connection connection;
//一個操作會話
private Session session;
//目的地,其實就是連接到哪個隊列,如果是點對點,那麼它的實現是Queue,如果是訂閱模式,那它的實現是Topic
private Destination destination;
//生產者,就是產生數據的對象
private MessageProducer producer;
public static void main(String[] args) {
TestQueueSend send = new TestQueueSend();
send.start();
}
public void start(){
try {
//根據用戶名,密碼,url創建一個連接工廠
factory = new ActiveMQConnectionFactory(userName, password, brokerURL);
//從工廠中獲取一個連接
connection = factory.createConnection();
//測試過這個步驟不寫也是可以的,但是網上的各個文檔都寫了
connection.start();
//創建一個session
//第一個參數:是否支持事務,如果爲true,則會忽略第二個參數,被jms服務器設置爲SESSION_TRANSACTED
//第二個參數爲false時,paramB的值可爲Session.AUTO_ACKNOWLEDGE,Session.CLIENT_ACKNOWLEDGE,DUPS_OK_ACKNOWLEDGE其中一個。
//Session.AUTO_ACKNOWLEDGE爲自動確認,客戶端發送和接收消息不需要做額外的工作。哪怕是接收端發生異常,也會被當作正常發送成功。
//Session.CLIENT_ACKNOWLEDGE爲客戶端確認。客戶端接收到消息後,必須調用javax.jms.Message的acknowledge方法。jms服務器纔會當作發送成功,並刪除消息。
//DUPS_OK_ACKNOWLEDGE允許副本的確認模式。一旦接收方應用程序的方法調用從處理消息處返回,會話對象就會確認消息的接收;而且允許重複確認。
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//創建一個到達的目的地,其實想一下就知道了,activemq不可能同時只能跑一個隊列吧,這裏就是連接了一個名爲"text-msg"的隊列,這個會話將會到這個隊列,當然,如果這個隊列不存在,將會被創建
destination = session.createQueue("text-msg");
//從session中,獲取一個消息生產者
producer = session.createProducer(destination);
//設置生產者的模式,有兩種可選
//DeliveryMode.PERSISTENT 當activemq關閉的時候,隊列數據將會被保存
//DeliveryMode.NON_PERSISTENT 當activemq關閉的時候,隊列裏面的數據將會被清空
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
//創建一條消息,當然,消息的類型有很多,如文字,字節,對象等,可以通過session.create..方法來創建出來
TextMessage textMsg = session.createTextMessage("呵呵");
for(int i = 0 ; i < 100 ; i ++){
//發送一條消息
producer.send(textMsg);
}
System.out.println("發送消息成功");
//即便生產者的對象關閉了,程序還在運行哦
producer.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
1.2點對點的接收方
package com.itsiji.test.queue;
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.ActiveMQConnectionFactory;
public class TestQueueReceive {
//連接賬號
private String userName = "";
//連接密碼
private String password = "";
//連接地址
private String brokerURL = "tcp://127.0.0.1:61616";
//connection的工廠
private ConnectionFactory factory;
//連接對象
private Connection connection;
//一個操作會話
private Session session;
//目的地,其實就是連接到哪個隊列,如果是點對點,那麼它的實現是Queue,如果是訂閱模式,那它的實現是Topic
private Destination destination;
//消費者,就是接收數據的對象
private MessageConsumer consumer;
public static void main(String[] args) {
TestQueueReceive receive = new TestQueueReceive();
receive.start();
}
public void start(){
try {
//根據用戶名,密碼,url創建一個連接工廠
factory = new ActiveMQConnectionFactory(userName, password, brokerURL);
//從工廠中獲取一個連接
connection = factory.createConnection();
//測試過這個步驟不寫也是可以的,但是網上的各個文檔都寫了
connection.start();
//創建一個session
//第一個參數:是否支持事務,如果爲true,則會忽略第二個參數,被jms服務器設置爲SESSION_TRANSACTED
//第二個參數爲false時,paramB的值可爲Session.AUTO_ACKNOWLEDGE,Session.CLIENT_ACKNOWLEDGE,DUPS_OK_ACKNOWLEDGE其中一個。
//Session.AUTO_ACKNOWLEDGE爲自動確認,客戶端發送和接收消息不需要做額外的工作。哪怕是接收端發生異常,也會被當作正常發送成功。
//Session.CLIENT_ACKNOWLEDGE爲客戶端確認。客戶端接收到消息後,必須調用javax.jms.Message的acknowledge方法。jms服務器纔會當作發送成功,並刪除消息。
//DUPS_OK_ACKNOWLEDGE允許副本的確認模式。一旦接收方應用程序的方法調用從處理消息處返回,會話對象就會確認消息的接收;而且允許重複確認。
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//創建一個到達的目的地,其實想一下就知道了,activemq不可能同時只能跑一個隊列吧,這裏就是連接了一個名爲"text-msg"的隊列,這個會話將會到這個隊列,當然,如果這個隊列不存在,將會被創建
destination = session.createQueue("text-msg");
//根據session,創建一個接收者對象
consumer = session.createConsumer(destination);
//實現一個消息的監聽器
//實現這個監聽器後,以後只要有消息,就會通過這個監聽器接收到
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
try {
//獲取到接收的數據
String text = ((TextMessage)message).getText();
System.out.println(text);
} catch (JMSException e) {
e.printStackTrace();
}
}
});
//關閉接收端,也不會終止程序哦
// consumer.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
2.訂閱/發佈模式的實現代碼
2.1訂閱模式的發佈方
package com.itsiji.test.topic;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
public class TestTopicSend {
//連接賬號
private String userName = "";
//連接密碼
private String password = "";
//連接地址
private String brokerURL = "tcp://127.0.0.1:61616";
//connection的工廠
private ConnectionFactory factory;
//連接對象
private Connection connection;
//一個操作會話
private Session session;
//目的地,其實就是連接到哪個隊列,如果是點對點,那麼它的實現是Queue,如果是訂閱模式,那它的實現是Topic
private Destination destination;
//生產者,就是產生數據的對象
private MessageProducer producer;
public static void main(String[] args) {
TestTopicSend send = new TestTopicSend();
send.start();
}
public void start(){
try {
//根據用戶名,密碼,url創建一個連接工廠
factory = new ActiveMQConnectionFactory(userName, password, brokerURL);
//從工廠中獲取一個連接
connection = factory.createConnection();
//測試過這個步驟不寫也是可以的,但是網上的各個文檔都寫了
connection.start();
//創建一個session
//第一個參數:是否支持事務,如果爲true,則會忽略第二個參數,被jms服務器設置爲SESSION_TRANSACTED
//第二個參數爲false時,paramB的值可爲Session.AUTO_ACKNOWLEDGE,Session.CLIENT_ACKNOWLEDGE,DUPS_OK_ACKNOWLEDGE其中一個。
//Session.AUTO_ACKNOWLEDGE爲自動確認,客戶端發送和接收消息不需要做額外的工作。哪怕是接收端發生異常,也會被當作正常發送成功。
//Session.CLIENT_ACKNOWLEDGE爲客戶端確認。客戶端接收到消息後,必須調用javax.jms.Message的acknowledge方法。jms服務器纔會當作發送成功,並刪除消息。
//DUPS_OK_ACKNOWLEDGE允許副本的確認模式。一旦接收方應用程序的方法調用從處理消息處返回,會話對象就會確認消息的接收;而且允許重複確認。
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//創建一個到達的目的地,其實想一下就知道了,activemq不可能同時只能跑一個隊列吧,這裏就是連接了一個名爲"text-msg"的隊列,這個會話將會到這個隊列,當然,如果這個隊列不存在,將會被創建
//=======================================================
//點對點與訂閱模式唯一不同的地方,就是這一行代碼,點對點創建的是Queue,而訂閱模式創建的是Topic
destination = session.createTopic("topic-text");
//=======================================================
//從session中,獲取一個消息生產者
producer = session.createProducer(destination);
//設置生產者的模式,有兩種可選
//DeliveryMode.PERSISTENT 當activemq關閉的時候,隊列數據將會被保存
//DeliveryMode.NON_PERSISTENT 當activemq關閉的時候,隊列裏面的數據將會被清空
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
//創建一條消息,當然,消息的類型有很多,如文字,字節,對象等,可以通過session.create..方法來創建出來
TextMessage textMsg = session.createTextMessage("哈哈");
long s = System.currentTimeMillis();
for(int i = 0 ; i < 100 ; i ++){
//發送一條消息
producer.send(textMsg);
}
long e = System.currentTimeMillis();
System.out.println("發送消息成功");
System.out.println(e - s);
//即便生產者的對象關閉了,程序還在運行哦
producer.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
2.2訂閱模式的接收方
package com.itsiji.test.topic;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
public class TestTopicReceive {
//連接賬號
private String userName = "";
//連接密碼
private String password = "";
//連接地址
private String brokerURL = "tcp://127.0.0.1:61616";
//connection的工廠
private ConnectionFactory factory;
//連接對象
private Connection connection;
//一個操作會話
private Session session;
//目的地,其實就是連接到哪個隊列,如果是點對點,那麼它的實現是Queue,如果是訂閱模式,那它的實現是Topic
private Destination destination;
//生產者,就是產生數據的對象
private MessageProducer producer;
public static void main(String[] args) {
TestTopicReceive send = new TestTopicReceive();
send.start();
}
public void start(){
try {
//根據用戶名,密碼,url創建一個連接工廠
factory = new ActiveMQConnectionFactory(userName, password, brokerURL);
//從工廠中獲取一個連接
connection = factory.createConnection();
//測試過這個步驟不寫也是可以的,但是網上的各個文檔都寫了
connection.start();
//創建一個session
//第一個參數:是否支持事務,如果爲true,則會忽略第二個參數,被jms服務器設置爲SESSION_TRANSACTED
//第二個參數爲false時,paramB的值可爲Session.AUTO_ACKNOWLEDGE,Session.CLIENT_ACKNOWLEDGE,DUPS_OK_ACKNOWLEDGE其中一個。
//Session.AUTO_ACKNOWLEDGE爲自動確認,客戶端發送和接收消息不需要做額外的工作。哪怕是接收端發生異常,也會被當作正常發送成功。
//Session.CLIENT_ACKNOWLEDGE爲客戶端確認。客戶端接收到消息後,必須調用javax.jms.Message的acknowledge方法。jms服務器纔會當作發送成功,並刪除消息。
//DUPS_OK_ACKNOWLEDGE允許副本的確認模式。一旦接收方應用程序的方法調用從處理消息處返回,會話對象就會確認消息的接收;而且允許重複確認。
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//創建一個到達的目的地,其實想一下就知道了,activemq不可能同時只能跑一個隊列吧,這裏就是連接了一個名爲"text-msg"的隊列,這個會話將會到這個隊列,當然,如果這個隊列不存在,將會被創建
//=======================================================
//點對點與訂閱模式唯一不同的地方,就是這一行代碼,點對點創建的是Queue,而訂閱模式創建的是Topic
destination = session.createTopic("topic-text");
//=======================================================
//從session中,獲取一個消息生產者
producer = session.createProducer(destination);
//設置生產者的模式,有兩種可選
//DeliveryMode.PERSISTENT 當activemq關閉的時候,隊列數據將會被保存
//DeliveryMode.NON_PERSISTENT 當activemq關閉的時候,隊列裏面的數據將會被清空
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
//創建一條消息,當然,消息的類型有很多,如文字,字節,對象等,可以通過session.create..方法來創建出來
TextMessage textMsg = session.createTextMessage("哈哈");
long s = System.currentTimeMillis();
for(int i = 0 ; i < 100 ; i ++){
//發送一條消息
textMsg.setText("哈哈" + i);
producer.send(textMsg);
}
long e = System.currentTimeMillis();
System.out.println("發送消息成功");
System.out.println(e - s);
//即便生產者的對象關閉了,程序還在運行哦
producer.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
3.發送消息的數據類型
javax.jms.Message 這個接口,只要是這個接口的數據,都可以被髮送
//純字符串的數據
session.createTextMessage();
//序列化的對象
session.createObjectMessage();
//流,可以用來傳遞文件等
session.createStreamMessage();
//用來傳遞字節
session.createBytesMessage();
//這個方法創建出來的就是一個map,可以把它當作map來用,當你看了它的一些方法,你就懂了
session.createMapMessage();
//這個方法,拿到的是javax.jms.Message,是所有message的接口
session.createMessage();