ActiveMQ實例

1、新建marven項目jms-test


2、在pom.xml導入相關jar包


3、pox.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.learn.jms</groupId>
<artifactId>jms-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>


<name>jms-test</name>
<url>http://maven.apache.org</url>


<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<org.springframework.version>4.3.12.RELEASE</org.springframework.version>
</properties>


<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>


<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.7.0</version>
<exclusions>
<exclusion>
<artifactId>spring-context</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>


</dependencies>
</project>


4、新建三個資源文件,common.xml,consumer-jms.xml,producer-jms.xml


common.xml配置如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:annotation-config/>

<!-- activeMQ 爲我們提供的  ConnectionFactory-->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.3.205:61616"/>
</bean>
<!-- spring jms 爲我們提供的連接池 -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="targetConnectionFactory"></property>
</bean>
<!-- 一個隊列的目的地 點對點 -->
<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="cyc_queue_test"></constructor-arg>
</bean>
<!-- 一個主題的目的地 發佈訂閱 -->
<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="cyc_topic_test"></constructor-arg>
</bean>

</beans>


consumer-jms.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 導入公共配置 -->
<import resource="common.xml"/>
<!-- 配置消息監聽器 -->
<bean id="consumerMessageListener" class="com.learn.jms.consumer.ConsumerMessageListener"></bean>
<!-- 配置消息監聽容器 -->
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"></property>
<!-- <property name="destination" ref="queueDestination"></property> -->
<property name="destination" ref="topicDestination"></property>
<property name="messageListener" ref="consumerMessageListener"></property>
</bean>

</beans>


producer-jms.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 導入公共配置 -->
<import resource="common.xml"/>

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory"></property>
</bean>
<bean class="com.learn.jms.producer.ProducerServiceImpl"></bean>
</beans>


5、新建生產者包com.learn.jms.producer


6、接口:ProducerService

package com.learn.jms.producer;



public interface ProducerService {
/**
* 發送消息 
* @param message
*/
void sendMessage(String message);
}

7、生產者實現類ProducerServiceImpl 

package com.learn.jms.producer;


import javax.annotation.Resource;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;


public class ProducerServiceImpl implements ProducerService {
@Autowired
JmsTemplate jmsTemplate;
@Resource(name = "topicDestination")
// @Resource(name = "queueDestination")
Destination destination;

@Override
public void sendMessage(final String message) {
//使用jmsTemlate 發送消息
jmsTemplate.send(destination,new MessageCreator() {
//創建一個消息
@Override
public Message createMessage(Session session) throws JMSException {
TextMessage textMessage = session.createTextMessage(message);
return textMessage;
}
});
System.out.println("【發送消息】Message:"+message);
}


}


8、生產者生產消息測試類AppProducer 

package com.learn.jms.producer;


import org.springframework.context.support.ClassPathXmlApplicationContext;


public class AppProducer {
public static void main(String[] args) {
ClassPathXmlApplicationContext  context = new ClassPathXmlApplicationContext("spring/producer-jms.xml");
ProducerService producerService = context.getBean(ProducerService.class);

for (int i = 0; i < 10; i++) {
producerService.sendMessage("test"+i);
}
context.close();
}
}


9、新建消費者包com.learn.jms.consumer


10、消費者監聽器ConsumerMessageListener 

package com.learn.jms.consumer;


import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;


public class ConsumerMessageListener implements MessageListener{


@Override
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("接受消息"+textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}

}


}


11、消費者接受消息測試

package com.learn.jms.consumer;


import org.springframework.context.support.ClassPathXmlApplicationContext;


public class AppConsumer {
public static void main(String[] args) {
ClassPathXmlApplicationContext  context = new ClassPathXmlApplicationContext("spring/consumer-jms.xml");
// ConsumerMessageListener producerService = context.getBean(ConsumerMessageListener.class);

}

}


隊列(Queue)和主題(Topic)是JMS支持的兩種消息傳遞模型:
        1、點對點(point-to-point,簡稱PTP)Queue消息傳遞模型:
        通過該消息傳遞模型,一個應用程序(即消息生產者)可以向另外一個應用程序(即消息消費者)發送消息。在此傳遞模型中,消息目的地類型是隊列(即Destination接口實現類實例由Session接口實現類實例通過調用其createQueue方法並傳入隊列名稱而創建)。消息首先被傳送至消息服務器端特定的隊列中,然後從此對列中將消息傳送至對此隊列進行監聽的某個消費者。同一個隊列可以關聯多個消息生產者和消息消費者,但一條消息僅能傳遞給一個消息消費者。如果多個消息消費者正在監聽隊列上的消息,,JMS消息服務器將根據“先來者優先”的原則確定由哪個消息消費者接收下一條消息。如果沒有消息消費者在監聽隊列,消息將保留在隊列中,直至消息消費者連接到隊列爲止。這種消息傳遞模型是傳統意義上的懶模型或輪詢模型。在此模型中,消息不是自動推動給消息消費者的,而是要由消息消費者從隊列中請求獲得。 
        2、發佈/訂閱(publish/subscribe,簡稱pub/sub)Topic消息傳遞模型:

        通過該消息傳遞模型,應用程序能夠將一條消息發送給多個消息消費者。在此傳送模型中,消息目的地類型是主題(即Destination接口實現類實例由Session接口實現類實例通過調用其createTopic方法並傳入主題名稱而創建)。消息首先由消息生產者發佈至消息服務器中特定的主題中,然後由消息服務器將消息傳送至所有已訂閱此主題的消費者。主題目標也支持長期訂閱。長期訂閱表示消費者已註冊了主題目標,但在消息到達目標時該消費者可以處於非活動狀態。當消費者再次處於活動狀態時,將會接收該消息。如果消費者均沒有註冊某個主題目標,該主題只保留註冊了長期訂閱的非活動消費者的消息。與PTP消息傳遞模型不同,pub/sub消息傳遞模型允許多個主題訂閱者接收同一條消息。JMS一直保留消息,直至所有主題訂閱者都接收到消息爲止。pub/sub消息傳遞模型基本上是一個推模型。在該模型中,消息會自動廣播,消息消費者無須通過主動請求或輪詢主題的方法來獲得新的消息。 

        具體區別對比如下:

類型

Topic

Queue

概要

Publish Subscribe messaging 發佈訂閱消息

Point-to-Point 點對點

有無狀態

topic數據默認不落地,是無狀態的。

Queue數據默認會在mq服務器上以文件形式保存,比如Active MQ一般保存在$AMQ_HOME\data\kr-store\data下面。也可以配置成DB存儲。

完整性保障

並不保證publisher發佈的每條數據,Subscriber都能接受到。

Queue保證每條數據都能被receiver接收。

消息是否會丟失

一般來說publisher發佈消息到某一個topic時,只有正在監聽該topic地址的sub能夠接收到消息;如果沒有sub在監聽,該topic就丟失了。

Sender發送消息到目標Queue,receiver可以異步接收這個Queue上的消息。Queue上的消息如果暫時沒有receiver來取,也不會丟失。

消息發佈接收策略

一對多的消息發佈接收策略,監聽同一個topic地址的多個sub都能收到publisher發送的消息。Sub接收完通知mq服務器

一對一的消息發佈接收策略,一個sender發送的消息,只能有一個receiver接收。receiver接收完後,通知mq服務器已接收,mq服務器對queue裏的消息採取刪除或其他操作。


發佈了14 篇原創文章 · 獲贊 9 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章