ActiveMQ

张Blog發表於2024-04-09

ActiveMQ

下載地址

ActiveMQ官網:http://activemq.apache.org/

ActiveMQ的所有版本下載地址:http://activemq.apache.org/download-archives.html

ActiveMQ原理

這裡寫圖片描述

首先來看本地通訊的情況,應用程式A和應用程式B執行於同一系統A,它們之間可以藉助訊息佇列技術進行彼此的通訊:應用程式A向佇列1傳送一條資訊,而當應用程式B需要時就可以得到該資訊。

其次是遠端通訊的情況,如果資訊傳輸的目標改為在系統B上的應用程式C,這種變化不會對應用程式A產生影響,應用程式A向佇列2傳送一條資訊,系統A的MQ發現Q2所指向的目的佇列實際上位於系統B,它將資訊放到本地的一個特殊佇列-傳輸佇列(Transmission Queue)。我們建立一條從系統A到系統B的訊息通道,訊息通道代理將從傳輸佇列中讀取訊息,並傳遞這條資訊到系統B,然後等待確認。只有MQ接到系統B成功收到資訊的確認之後,它才從傳輸佇列中真正將該資訊刪除。如果通訊線路不通,或系統B不在執行,資訊會留在傳輸佇列中,直到被成功地傳送到目的地。這是MQ最基本而最重要的技術–確保資訊傳輸,並且是一次且僅一次(once-and-only-once)的傳遞。

MQ提供了用於應用整合的鬆耦合的連線方法,因為共享資訊的應用不需要知道彼此物理位置(網路地址);不需要知道彼此間怎樣建立通訊;不需要同時處於執行狀態;不需要在同樣的作業系統或網路環境下執行。

JMS框架基本角色和程式設計模組

  • JMS Message Producers : 訊息生產者,向訊息佇列提供訊息
  • JMS Provider(Broker) : JMS提供商,如ActiveMQ,提供JMS Queues/Topics服務
  • JMS Message listener/Consumer :接收並使用訊息

queue的使用

這裡寫圖片描述

Product

開發步驟:

  1. 建立ActiveMQConnectionFactory,建立工廠需要ip和埠號,指定的是tcp協議
  2. 從工廠中獲取連線
  3. 使用連線的start方法,開啟連線
  4. 使用連線獲取session物件
  5. 使用session建立Destination,就是建立queue,(可以設定queue(點對點)和topic(訂閱)
  6. 使用session建立Product,訊息的是生產者
  7. 建立訊息物件TextMessage,設定訊息
  8. 傳送訊息
  9. 釋放資源,關閉Product、session、connection
public static void main(String[] args) throws Exception {
		// 1. 建立連線工廠ActiveMQConnectionFactory,需要ip和埠61616
		ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://192.168.37.130:61616");

		// 2. 從連線工廠中建立連線物件
		Connection connection = factory.createConnection();

		// 3. 執行start方法開啟連線
		connection.start();

		// 4. 從連線中建立session物件
		// 第一個引數,是否開啟事務,JTA分散式事務
		// 第二個引數,是否自動應答,如果第一個引數為true,第二個引數失效
		Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

		// 5. 從session中建立Destination物件,設定queue名稱(有兩種型別queue和topic)
		Queue queue = session.createQueue("test-queue");

		// 6. 從session中建立Product物件
		MessageProducer producer = session.createProducer(queue);

		// 7. 建立訊息物件
		TextMessage textMessage = new ActiveMQTextMessage();
		// 設定訊息內容
		textMessage.setText("開始發訊息!");

		// 8. 傳送訊息
		producer.send(textMessage);

		// 9. 關閉session、連線
		producer.close();
		session.close();
		connection.close();
	}

Consumer

開發步驟

  1. 建立連線工廠ActiveMQConnectionFactory,需要ip和埠
  2. 從連線工廠中建立連線物件
  3. 執行start方法開始連線
  4. 從連線中建立session物件
  5. 從session中建立Destination物件,設定queue名稱(有兩種型別queue和topic)
  6. 從session中建立Consumer物件
  7. 接收訊息
  8. 列印結果
  9. 關閉session、連線
public static void main(String[] args) throws Exception {
		// 1. 建立連線工廠ActiveMQConnectionFactory,需要ip和埠61616
		ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://192.168.37.130:61616");

		// 2. 使用工廠建立連線
		Connection connection = factory.createConnection();

		// 3. 使用start開啟連線
		connection.start();

		// 4. 從連線中建立session物件
		Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

		// 5. 從session中建立Destination物件,設定queue名字
		Queue queue = session.createQueue("test-queue");

		// 6. 從session中建立Consumer
		MessageConsumer consumer = session.createConsumer(queue);

		// 7, 接收訊息,直接獲取
		while (true) {
			// 訊息超時時間是20秒
			Message message = consumer.receive(20000);
			// 如果訊息為空,則跳出死迴圈
			if (message == null) {
				break;
			}

			// 8. 列印訊息
			if (message instanceof TextMessage) {
				// 獲取訊息
				TextMessage textMessage = (TextMessage) message;
				// 列印
				System.out.println(textMessage.getText());						}
		}

		// 9. 關閉session、連線等
		consumer.close();
		session.close();
		connection.close();

	}

使用監聽器

public static void main(String[] args) throws Exception {
		// 1. 建立連線工廠ActiveMQConnectionFactory,需要ip和埠61616
		ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://192.168.37.130:61616");

		// 2. 使用工廠建立連線
		Connection connection = factory.createConnection();

		// 3. 使用start開啟連線
		connection.start();

		// 4. 從連線中建立session物件
		Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

		// 5. 從session中建立Destination物件,設定queue名字
		Queue queue = session.createQueue("test-queue");

		// 6. 從session中建立Consumer
		MessageConsumer consumer = session.createConsumer(queue);

		// 7.接收訊息
		// 監聽器的方式實際上是開啟了一個新的執行緒,專門處理訊息的接受
		// 現在的情況是,主執行緒執行完就結束了,新的執行緒也跟著沒了
		consumer.setMessageListener(new MessageListener() {

			@Override
			public void onMessage(Message message) {
				if (message instanceof TextMessage) {
					// 獲取訊息
					TextMessage textMessage = (TextMessage) message;
					try {
						// 列印
						System.out.println(textMessage.getText());
					} catch (JMSException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

				}

			}
		});

		// 讓主執行緒等待一會,監聽器能夠有時間執行
		Thread.sleep(10000);

		// 9. 關閉session、連線等
		consumer.close();
		session.close();
		connection.close();

	}

topic的使用

這裡寫圖片描述

Product

public static void main(String[] args) throws Exception {
		// 1. 建立連線工廠ActiveMQConnectionFactory
		ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(
				"tcp://192.168.37.130:61616");

		// 2. 使用工廠建立連線
		Connection connection = activeMQConnectionFactory.createConnection();

		// 3. 使用start方法開啟連線
		connection.start();

		// 4. 從連線建立session
		Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

		// 5. 從session建立Destination物件,設定topic名稱
		Topic topic = session.createTopic("test-topic");

		// 6. 從session建立Product
		MessageProducer producer = session.createProducer(topic);

		// 7. 建立訊息物件
		TextMessage textMessage = new ActiveMQTextMessage();
		textMessage.setText("topic訊息");

		// 8. 傳送訊息
		producer.send(textMessage);

		// 9. 關閉session、連線等
		producer.close();
		session.close();
		connection.close();
	}

}

Consumer1

public static void main(String[] args) throws Exception {
		// 1. 建立連線工廠ActiveMQConnectionFactory
		ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(
				"tcp://192.168.37.130:61616");

		// 2. 從連線工廠建立連線
		Connection connection = activeMQConnectionFactory.createConnection();

		// 3. 使用start方法開啟連線
		connection.start();

		// 4. 從連線建立session物件
		Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

		// 5. 從session建立安Destination,設定topic名稱
		Topic topic = session.createTopic("test-topic");

		// 6. 從session建立Consumer物件
		MessageConsumer consumer = session.createConsumer(topic);

		// 7. 接收訊息,直接接受
		while (true) {
			Message message = consumer.receive(20000);

			if (message == null) {
				break;
			}

			if (message instanceof TextMessage) {
				TextMessage textMessage = (TextMessage) message;
				// 8. 列印訊息
				System.out.println(textMessage.getText());
			}
		}

		// 9. 關閉session、訊息等
		consumer.close();
		session.close();
		connection.close();

	}

Consumer2

public static void main(String[] args) throws Exception {
		// 1. 建立連線工廠ActiveMQConnectionFactory
		ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(
				"tcp://192.168.37.130:61616");

		// 2. 從連線工廠建立連線
		Connection connection = activeMQConnectionFactory.createConnection();

		// 3. 使用start方法開啟連線
		connection.start();

		// 4. 從連線建立session物件
		Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

		// 5. 從session建立安Destination,設定topic名稱
		Topic topic = session.createTopic("test-topic");

		// 6. 從session建立Consumer物件
		MessageConsumer consumer = session.createConsumer(topic);

		// 7. 接收訊息,直接接受
		// while (true) {
		// Message message = consumer.receive(20000);
		//
		// if (message == null) {
		// break;
		// }
		//
		// if (message instanceof TextMessage) {
		// TextMessage textMessage = (TextMessage) message;
		// // 8. 列印訊息
		// System.out.println(textMessage.getText());
		// }
		// }

		// 7.接受訊息,使用監聽器
		consumer.setMessageListener(new MessageListener() {

			@Override
			public void onMessage(Message message) {
				if (message instanceof TextMessage) {
					TextMessage textMessage = (TextMessage) message;

					try {
						// 列印訊息
						System.out.println(textMessage.getText());
					} catch (JMSException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		});

		// 等待監聽器執行
		Thread.sleep(10000);

		// 9. 關閉session、訊息等
		consumer.close();
		session.close();
		connection.close();

	}

ActiveMQ整合Spring

加入依賴

<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>
	<parent>
		<groupId>com.taotao</groupId>
		<artifactId>taotao-parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<groupId>cn.itcast.activemq</groupId>
	<artifactId>itcast-activemq</artifactId>
	<version>1.0.0-SNAPSHOT</version>

	<dependencies>
		<!-- 加入ActiveMQ依賴 -->
		<dependency>
			<groupId>org.apache.activemq</groupId>
			<artifactId>activemq-all</artifactId>
		</dependency>

		<!-- 加入spring-jms依賴 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jms</artifactId>
		</dependency>

		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
		</dependency>
	</dependencies>
</project>

訊息傳送

  1. 建立spring容器
  2. 從容器中獲取JMSTemplate物件,傳送訊息
  3. 定義Destination
  4. 使用JMSTemplate物件傳送訊息
public class Product {

	public static void main(String[] args) {
		// 1. 建立spring容器
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
				"applicationContext-activemq.xml");

		// 2. 從容器中獲取JMSTemplate物件
		JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);

		// 3. 從容器中獲取Destination物件
		Destination destination = context.getBean(Destination.class);

		// 4. 使用JMSTemplate傳送訊息
		jmsTemplate.send(destination, new MessageCreator() {

			@Override
			public Message createMessage(Session session) throws JMSException {
				// 建立訊息物件
				TextMessage textMessage = new ActiveMQTextMessage();

				// 設定訊息內容
				textMessage.setText("spring整合ActiveMQ");

				// 列印訊息
				System.out.println(textMessage.getText());

				return textMessage;
			}
		});
	}

}

訊息接受

  1. 建立一個類實現MessageListener 介面。業務處理在此類中實現。
  2. 在spring容器中配置DefaultMessageListenerContainer物件,引用MessageListener 實現類物件接收訊息。
public class MyMessageListener implements MessageListener {

	@Override
	public void onMessage(Message message) {
		if (message instanceof TextMessage) {
			TextMessage textMessage = (TextMessage) message;

			try {
				// 獲取訊息內容
				String msg = textMessage.getText();

				// 列印訊息
				System.out.println("接受訊息:" + msg);

			} catch (JMSException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

}

queue方式配置Spring

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jms="http://www.springframework.org/schema/jms"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 
	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
	http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-4.0.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">


	<!-- 真正可以產生Connection的ConnectionFactory,由對應的 JMS服務廠商提供 -->
	<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
		<property name="brokerURL" value="tcp://192.168.37.130:61616" />
	</bean>

	<!-- Spring用於管理真正的ConnectionFactory的ConnectionFactory -->
	<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
		<!-- 目標ConnectionFactory對應真實的可以產生JMS Connection的ConnectionFactory -->
		<property name="targetConnectionFactory" ref="targetConnectionFactory" />
	</bean>

	<!-- Spring提供的JMS工具類,它可以進行訊息傳送、接收等 -->
	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<!-- 這個connectionFactory對應的是我們定義的Spring提供的那個ConnectionFactory物件 -->
		<property name="connectionFactory" ref="connectionFactory" />
	</bean>

	<!--這個是佇列目的地,點對點的 -->
	<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg>
			<value>queue</value>
		</constructor-arg>
	</bean>

	<!--這個是主題目的地,一對多的 -->
	<!-- <bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic"> -->
	<!-- <constructor-arg value="topic" /> -->
	<!-- </bean> -->

	<!-- messageListener實現類 -->
	<bean id="myMessageListener" class="top.simba.activemq.spring.MyMessageListener"></bean>

	<!-- 配置一個jsm監聽容器 -->
	<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
		<property name="connectionFactory" ref="connectionFactory" />
		<property name="destination" ref="queueDestination" />
		<property name="messageListener" ref="myMessageListener" />
	</bean>

</beans>

topic方式配置Spring

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:jms="http://www.springframework.org/schema/jms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 
	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
	http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-4.0.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

	<!-- 真正可以產生Connection的ConnectionFactory,由對應的 JMS服務廠商提供 -->
	<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
		<property name="brokerURL" value="tcp://192.168.37.130:61616" />
	</bean>

	<!-- Spring用於管理真正的ConnectionFactory的ConnectionFactory -->
	<bean id="connectionFactory"
		class="org.springframework.jms.connection.SingleConnectionFactory">
		<!-- 目標ConnectionFactory對應真實的可以產生JMS Connection的ConnectionFactory -->
		<property name="targetConnectionFactory" ref="targetConnectionFactory" />
	</bean>

	<!-- Spring提供的JMS工具類,它可以進行訊息傳送、接收等 -->
	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<!-- 這個connectionFactory對應的是我們定義的Spring提供的那個ConnectionFactory物件 -->
		<property name="connectionFactory" ref="connectionFactory" />
	</bean>

	<!--這個是佇列目的地,點對點的 -->
	<!-- <bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue"> -->
	<!-- <constructor-arg> -->
	<!-- <value>queue</value> -->
	<!-- </constructor-arg> -->
	<!-- </bean> -->

	<!--這個是主題目的地,一對多的 -->
	<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
		<constructor-arg value="topic" />
	</bean>

	<!-- messageListener實現類 -->
	<bean id="myMessageListener" class="top.simba.activemq.spring.MyMessageListener"></bean>
	
	<!-- messageListener實現類 -->
	<bean id="myMessageListener2" class="top.simba.activemq.spring.MyMessageListener2"></bean>

	<!-- 配置一個jsm監聽容器 -->
	<bean id="jmsContainer"
		class="org.springframework.jms.listener.DefaultMessageListenerContainer">
		<property name="connectionFactory" ref="connectionFactory" />
		<property name="destination" ref="topicDestination" />
		<property name="messageListener" ref="myMessageListener" />
	</bean>
	
	<!-- 配置一個jsm監聽容器 -->
	<bean id="jmsContainer2"
		class="org.springframework.jms.listener.DefaultMessageListenerContainer">
		<property name="connectionFactory" ref="connectionFactory" />
		<property name="destination" ref="topicDestination" />
		<property name="messageListener" ref="myMessageListener2" />
	</bean>

</beans>

ActiveMQ安裝

1.上傳ActiveMQ,並解壓

這裡寫圖片描述

2.進入解壓後的資料夾的bin目錄,啟動ActiveMQ

[root@root bin]# ./activemq start

這裡寫圖片描述

3.訪問http://192.168.37.130:8161/admin/

原始賬號:admin

原始密碼:admin

這裡寫圖片描述

相關文章