1. ActiveMQ入門
前面的文章已經寫過MQ的相關概念,這裏不再贅述。
1.1 ActiveMQ是什麼
ActiveMQ是Apache下的開源項目,完全支持JMS1.1和J2EE1.4規範的JMS Provider實現。
1.2 ActiveMQ的特點
- 支持多種語言編寫客戶端
- 對Spring的支持,很容易和Spring整合
- 支持多種傳輸協議:TCP,SSL,NIO,UDP等
- 支持Ajax請求
1.3 ActiveMQ的安裝
1.3.1 官網下載
解壓後的文件夾結構: |
1.3.2 啓動ActiveMQ
直接雙擊這個“wrapper.exe”即可 |
之後可以在瀏覽器輸入http://localhost:8161/ |
1.3.3 進入管理中心
點擊Manage ActiveMQ broker,會彈出身份驗證,輸入admin,admin即可 |
1.4 搭建Maven工程框架
<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.linkedbear</groupId>
<artifactId>ActiveMQ-Demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<activemq.version>5.15.4</activemq.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- ActiveMQ -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-client</artifactId>
<version>${activemq.version}</version>
</dependency>
<!-- 熱部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
1.5 創建工程目錄結構
之前的文章中寫過,JMS的消息傳遞有兩種模式,前面的RocketMQ中只寫了一對一模式,本篇文章將會編寫兩種模式。
1.6 一對一模式的Queue
1.6.1 生產者
/**
* 生產者Controller
* @Title ProducerQueueController
* @author LinkedBear
* @Time 2018年8月3日 下午4:52:49
*/
@Controller
public class ProducerQueueController {
@RequestMapping("/queueProduceMessage")
@ResponseBody
public Map<String, Object> queueProduceMessage() throws Exception {
//JMS的使用比較類似於JDBC與Hibernate
//1. 創建一個連接工廠(類似於JDBC中的註冊驅動),需要傳入TCP協議的ActiveMQ服務地址
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
//2. 創建連接(類似於DriverManager.getConnection)
Connection connection = connectionFactory.createConnection();
//3. 開啓連接(ActiveMQ創建的連接是需要手動開啓的)
connection.start(); //注意不是open。。。
//4. 獲取session(類似於Hibernate中的session,都是用會話來進行操作)
//裏面有兩個參數,參數1爲是否開啓事務,參數2爲消息確認模式
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//5. 創建一對一的消息隊列
Queue queue = session.createQueue("test_queue");
//6. 創建一條消息
String text = "test queue message" + Math.random();
TextMessage message = session.createTextMessage(text);
//7. 消息需要發送方,要創建消息發送方(生產者),並綁定到某個消息隊列上
MessageProducer producer = session.createProducer(queue);
//8. 發送消息
producer.send(message);
//9. 關閉連接
producer.close();
session.close();
connection.close();
//------顯示發送的消息到視圖上------
Map<String, Object> map = new HashMap<>();
map.put("message", text);
return map;
}
}
1.6.2 消費者
/**
* 消費者Controller
* @Title ConsumerQueueController
* @author LinkedBear
* @Time 2018年8月3日 下午4:52:56
*/
@Controller
public class ConsumerQueueController {
@RequestMapping("/queueGetMessage1")
public void queueGetMessage1() throws Exception {
//1. 創建一個連接工廠,需要傳入TCP協議的ActiveMQ服務地址
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
//2. 創建連接
Connection connection = connectionFactory.createConnection();
//3. 開啓連接
connection.start(); //注意不是open。。。
//4. 獲取session
//裏面有兩個參數,參數1爲是否開啓事務,參數2爲消息確認模式
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//5. 創建一對一的消息隊列
Queue queue = session.createQueue("test_queue");
//------------前5步都是相同的,以下爲不同----------------
//6. 創建消費者
MessageConsumer consumer = session.createConsumer(queue);
//7. 使用監聽器監聽隊列中的消息
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
String text = textMessage.getText();
System.out.println("收到消息:" + text);
} catch (JMSException e) {
e.printStackTrace();
}
}
});
//由於設置監聽器後不能馬上結束方法,要在這裏加一個等待點
System.in.read();
//8. 關閉連接
consumer.close();
session.close();
connection.close();
}
@RequestMapping("/queueGetMessage2")
public void queueGetMessage2() throws Exception //(完全相同,不再重複)
}
1.6.3 運行結果
先執行兩個消息的消費者 |
執行http://localhost:8080/queueProduceMessage: 但是只收到一條消息 |
1.7 一對多模式的Topic
1.7.1 生產者
/**
* 生產者Controller
* @Title ProducerTopicController
* @author LinkedBear
* @Time 2018年8月3日 下午4:52:49
*/
@Controller
public class ProducerTopicController {
@RequestMapping("/topicProduceMessage")
@ResponseBody
public Map<String, Object> topicProduceMessage() throws Exception {
//JMS的使用比較類似於JDBC與Hibernate
//1. 創建一個連接工廠(類似於JDBC中的註冊驅動),需要傳入TCP協議的ActiveMQ服務地址
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
//2. 創建連接(類似於DriverManager.getConnection)
Connection connection = connectionFactory.createConnection();
//3. 開啓連接(ActiveMQ創建的連接是需要手動開啓的)
connection.start(); //注意不是open。。。
//4. 獲取session(類似於Hibernate中的session,都是用會話來進行操作)
//裏面有兩個參數,參數1爲是否開啓事務,參數2爲消息確認模式
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//5. 創建一對多的消息廣播
Topic topic = session.createTopic("test_topic");
//6. 創建一條消息
String text = "test topic message" + Math.random();
TextMessage message = session.createTextMessage(text);
//7. 消息需要發送方,要創建消息發送方(生產者),並廣播到某個消息廣播端上
MessageProducer producer = session.createProducer(topic);
//8. 發送消息
producer.send(message);
//9. 關閉連接
producer.close();
session.close();
connection.close();
//------顯示發送的消息到視圖上------
Map<String, Object> map = new HashMap<>();
map.put("message", text);
return map;
}
}
1.7.2 消費者
/**
* 消費者Controller
* @Title ConsumerTopicController
* @author LinkedBear
* @Time 2018年8月3日 下午4:52:56
*/
@Controller
public class ConsumerTopicController {
@RequestMapping("/topicGetMessage")
public void topicGetMessage() throws Exception {
//1. 創建一個連接工廠,需要傳入TCP協議的ActiveMQ服務地址
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
//2. 創建連接
Connection connection = connectionFactory.createConnection();
//3. 開啓連接
connection.start(); //注意不是open。。。
//4. 獲取session
//裏面有兩個參數,參數1爲是否開啓事務,參數2爲消息確認模式
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//5. 創建一對多的消息廣播
Topic topic = session.createTopic("test_topic");
//------------前5步都是相同的,以下爲不同----------------
//6. 創建消費者
MessageConsumer consumer = session.createConsumer(topic);
//7. 使用監聽器監聽隊列中的消息
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
String text = textMessage.getText();
System.out.println("收到消息:" + text);
} catch (JMSException e) {
e.printStackTrace();
}
}
});
//由於設置監聽器後不能馬上結束方法,要在這裏加一個等待點
System.in.read();
//8. 關閉連接
consumer.close();
session.close();
connection.close();
}
@RequestMapping("/topicGetMessage2")
public void topicGetMessage2() throws Exception //(完全相同,不再重複)
}
1.7.3 運行結果
先執行兩個消息的消費者 |
執行http://localhost:8080/topicProduceMessage: 這次收到了兩條消息 |
2. RocketMQ與ActiveMQ的對比
從這兩種消息中間件的編寫過程來看,兩種產品的區別是比較大的,下面就這兩種產品進行多方面對比。
參考文章:https://blog.csdn.net/jasonhui512/article/details/53231566
比較項 |
RocketMQ |
ActiveMQ |
語言支持 |
只支持Java |
多語言,Java爲主 |
可用性 |
分佈式 |
主從 |
JMS規範 |
常用的使用方式沒有遵循JMS |
嚴格遵循JMS規範 |
消息持久化 |
硬盤 |
內存,硬盤,數據庫 |
部署方式 |
獨立部署 |
獨立部署、嵌入應用,可以與Spring很好的整合 |
社區活躍 |
活躍 |
不很活躍 |