ActiveMQ 入门和与 Spring 整合
ActiveMQ
入门演示
activemq 依赖
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-client</artifactId>
<version>5.13.4</version>
</dependency>
Caused by: java.io.IOException: Transport scheme NOT recognized: [http]
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("http://192.168.20.131:61616");
Could not connect to broker URL: tcp://192.168.20.131:61616. Reason: java.net.ConnectException: Connection timed out: connect
消息传递方式 1. 点对点 2. 发布订阅
点对点
用消息队列实现,如果没有消费者,则消息会先存到消息队列中。一个消息只会被一个消费者消费。
package com.mozq;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
public class QueueProducer {
public static void main(String[] args) throws JMSException {
//创建连接工厂
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.20.131:61616");
//获取连接
Connection connection = connectionFactory.createConnection();
//启动连接
connection.start();
//获取会话
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//创建队列
Queue queue = session.createQueue("test_queue");
//创建生产者
MessageProducer producer = session.createProducer(queue);
//创建消息
TextMessage message = session.createTextMessage("欢迎来到消息中间件世界");
//发送
for (int i = 0; i < 5; i++) {
producer.send(message);
}
//关闭资源
producer.close();
session.close();
connection.close();
}
}
消费者可以调用重发方法进行消息的重发。次数和延迟。
RedeliveryPolicy
session.recover()
package com.mozq;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.RedeliveryPolicy;
import javax.jms.*;
import java.io.IOException;
public class QueueConsumer {
private static int i = 0;
public static void main(String[] args) throws JMSException, IOException {
//创建连接工厂
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.20.131:61616");
//重发策略
RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
redeliveryPolicy.setMaximumRedeliveries(2);
redeliveryPolicy.setRedeliveryDelay(3000);
((ActiveMQConnectionFactory) connectionFactory).setRedeliveryPolicy(redeliveryPolicy);
//获取连接
Connection connection = connectionFactory.createConnection();
//启动连接
connection.start();
//获取会话
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//创建队列
Queue queue = session.createQueue("test_queue");
//创建消费者
MessageConsumer consumer = session.createConsumer(queue);
//监听消息
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println(i++ + "消息处理");
int i = 1 / 0;
System.out.println("处理完成");
System.out.println(textMessage.getText());
} catch (Exception e) {
System.out.println("处理失败");
try {
session.recover();
} catch (JMSException e1) {
e1.printStackTrace();
}
}
}
});
System.in.read();
//关闭资源
session.close();
connection.close();
}
}
发布订阅
发布者发布消息时,如果没有消费者,则这个消息不会被消费。发布消息时一条消息会被所有已激活的消费者消费。
package com.mozq;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
public class TopicProducer {
private static final String url = "tcp://192.168.20.131:61616";
private static final String topicName = "test_topic";
public static void main(String[] args) throws JMSException {
//创建连接工厂
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
//获取连接
Connection connection = connectionFactory.createConnection();
//启动连接
connection.start();
//获取会话
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//创建主题
Topic topic = session.createTopic(topicName);
//创建生产者
MessageProducer producer = session.createProducer(topic);
//创建消息
TextMessage message = session.createTextMessage("欢迎来到消息中间件世界,主题消息");
//发送
for (int i = 0; i < 5; i++) {
producer.send(message);
}
//关闭资源
producer.close();
session.close();
connection.close();
}
}
package com.mozq;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
import java.io.IOException;
public class QueueConsumer {
public static void main(String[] args) throws JMSException, IOException {
//创建连接工厂
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.20.131:61616");
//获取连接
Connection connection = connectionFactory.createConnection();
//启动连接
connection.start();
//获取会话
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//创建队列
Queue queue = session.createQueue("test_queue");
//创建消费者
MessageConsumer consumer = session.createConsumer(queue);
//监听消息
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println(textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
});
System.in.read();
//关闭资源
session.close();
connection.close();
}
}
package com.mozq;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
import java.io.IOException;
public class TopicConsumer {
private static final String url = "tcp://192.168.20.131:61616";
private static final String topicName = "test_topic";
public static void main(String[] args) throws JMSException, IOException {
//创建连接工厂
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
//获取连接
Connection connection = connectionFactory.createConnection();
//启动连接
connection.start();
//获取会话
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//创建主题
Topic topic = session.createTopic(topicName);
//创建消费者
MessageConsumer consumer = session.createConsumer(topic);
//监听消息
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println(textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
});
System.in.read();
//关闭资源
session.close();
connection.close();
}
}
Spring 整合 ActiveMQ
spring-jms 依赖
<properties>
<spring.version>4.2.4.RELEASE</spring.version>
</properties>
<dependencies>
<!-- activemq 相关 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-client</artifactId>
<version>5.13.4</version>
</dependency>
<!-- 测试相关 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
</dependencies>
点到点
spring-jms-producer 配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jms="http://www.springframework.org/schema/jms"
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.xsd">
<context:component-scan base-package="cn.itcast.demo"></context:component-scan>
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.20.131:61616" />
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="targetConnectionFactory" />
</bean>
<!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory" />
</bean>
<!--点对点-->
<bean id="queueTextDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="queue_text" />
</bean>
<!-- 发布订阅 -->
<bean id="topicTextDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="topic_text" />
</bean>
</beans>
package cn.itcast.demo;
import org.apache.activemq.command.ActiveMQQueue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Component;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
@Component
public class QueueProducer {
@Autowired
private JmsTemplate jmsTemplate;
@Autowired
private ActiveMQQueue queueTextDestination;
public void sendTextMessage(String message){
jmsTemplate.send(queueTextDestination, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(message);
}
});
}
}
package cn.itcast.demo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-jms-producer.xml")
public class QueueProducerTest {
@Autowired
private QueueProducer queueProducer;
@Test
public void testSend(){
queueProducer.sendTextMessage("spring-jms 队列消息");
}
}
spring-jms-consumer 配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jms="http://www.springframework.org/schema/jms"
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.xsd">
<context:component-scan base-package="cn.itcast.demo" />
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.20.131:61616" />
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="targetConnectionFactory" />
</bean>
<!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory" />
</bean>
<!--点对点-->
<bean id="queueTextDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="queue_text" />
</bean>
<!-- 发布订阅 -->
<bean id="topicTextDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="topic_text" />
</bean>
<!-- 消息监听实现类 -->
<bean id="myTextMessageListener" class="cn.itcast.demo.MyTextMessageListener" />
<!-- 消息监听容器 -->
<bean id="defaultMessageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="queueTextDestination" />
<property name="messageListener" ref="myTextMessageListener" />
</bean>
</beans>
监听类
package cn.itcast.demo;
import org.springframework.stereotype.Component;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
@Component
public class MyTextMessageListener implements MessageListener {
@Override
public void onMessage(Message message) {
if(message instanceof TextMessage){
TextMessage textMessage = (TextMessage) message;
try {
String text = textMessage.getText();
System.out.println(text);
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
package cn.itcast.demo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.io.IOException;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-jms-consumer.xml")
public class QueueConsumerTest {
@Test
public void test(){
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}
}
发布订阅
发布
package cn.itcast.demo;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Component;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
@Component
public class TopicProducer {
@Autowired
private JmsTemplate jmsTemplate;
@Autowired
private ActiveMQTopic topicTextDestination;
public void sendTextMessage(String message){
jmsTemplate.send(topicTextDestination, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(message);
}
});
}
}
package cn.itcast.demo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-jms-producer.xml")
public class TopicProducerTest {
@Autowired
private TopicProducer topicProducer;
@Test
public void testSend(){
topicProducer.sendTextMessage("spring-jms 主题消息");
}
}
订阅
<!-- 发布订阅的目的地 -->
<bean id="topicTextDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="topic_text" />
</bean>
<!-- 消息监听实现类 -->
<bean id="myTextMessageListener" class="cn.itcast.demo.MyTextMessageListener" />
<!-- 消息监听容器 -->
<bean id="defaultMessageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="topicTextDestination" />
<property name="messageListener" ref="myTextMessageListener" />
</bean>
消息监听器实现方法和点对点模式的相同。
activemq 使用思路
遵循 jms 规范
2种消息传递方式
- queue 点到点方式 一个消息只会被消费一次
- topic 发布订阅方式 一个消息被多个消费者消费
5种消息类型
TextMessage
ObjectMessage
MapMessage
BytesMessage
StreamMessage
mq 的使用场景:
完成系统间的解耦。消费者调用生产者的代码时不需要生产者返回结果。
用户注册,发送验证邮件。
商品审核,生成静态页面,更新 solr 数据。
spring 和 activemq 整合思路
- 生产者 (JmsTemplate)
JmsTemplate 需要注入一个 Spring 提供的连接工厂, 这个连接工厂需要一个 activemq 的连接工厂,同时使用 JmsTemplate 发送消息时,需要传入 Destination 。
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.20.131:61616" />
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="targetConnectionFactory" />
</bean>
<!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory" />
</bean>
<!--点对点-->
<bean id="queueTextDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="queue_text" />
</bean>
<!-- 发布订阅 -->
<bean id="topicTextDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="topic_text" />
</bean>
- 消费者 (DefaultMessageListenerContainer)
消息监听容器需要,1. 消息监听器,2. spring 的连接工厂, 而 spring 的连接工厂又需要 activemq 提供的连接工厂,3. 目标 Destination 。消息的处理在消息监听器中,spring 启动时将会自动创建连接,当消息被接收时监听方法被自动调用。
<!-- 消息监听容器 生成页面 -->
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="topicPageDeleteDestination" />
<property name="messageListener" ref="pageDeleteListener" />
</bean>
问题
org.springframework.jms.connection.ConnectionFactoryUtils.releaseConnection(ConnectionFactoryUtils.java:83)Could not close JMS Connection
org.apache.activemq.ConnectionFailedException: The JMS connection has failed: java.io.EOFException
原因:
重启下服务好了。
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'temListImportMessageListenerContainer' defined in file [D:\Code\IdeaProject\IdeaCode\pinyougou-work\pinyougou-parent\pinyougou-search-service\target\classes\spring\applicationContext-jms.xml]: Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'messageListener' threw exception; nested exception is java.lang.IllegalArgumentException: Message listener needs to be of type [javax.jms.MessageListener] or [org.springframework.jms.listener.SessionAwareMessageListener]
原因:
没有实现 MessageListener 接口。
org.springframework.jms.UncategorizedJmsException: Uncategorized exception occured during JMS processing;
Caused by: org.apache.activemq.ConnectionFailedException: The JMS connection has failed: java.io.EOFException
原因:
重启下服务好了。
ActiveMQ 入门和与 Spring 整合的更多相关文章
- RabbitMQ入门到进阶(Spring整合RabbitMQ&SpringBoot整合RabbitMQ)
1.MQ简介 MQ 全称为 Message Queue,是在消息的传输过程中保存消息的容器.多用于分布式系统 之间进行通信. 2.为什么要用 MQ 1.流量消峰 没使用MQ 使用了MQ 2.应用解耦 ...
- ActiveMQ安装使用与spring整合配置教程
https://blog.csdn.net/qq_22075041/article/details/77602996
- ActiveMQ之一--ActiveMQ入门
MQ的消费-生产者模型的一个典型的代表,一端往消息队列中不断的写入消息,而另一端则可以读取或者订阅队列中的消息.MQ和JMS类似,但不同的是JMS是SUN JAVA消息中间件服务的一个标准和API定义 ...
- ActiveMQ (三) Spring整合JMS入门
Spring整合JMS入门 前提:安装好了ActiveMQ ActiveMQ安装 Demo结构: 生产者项目springjms_producer: pom.xml <?xml versio ...
- 消息中间件ActiveMQ及Spring整合JMS
一 .消息中间件的基本介绍 1.1 消息中间件 1.1.1 什么是消息中间件 消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成.通过提供消息传递和消息排 ...
- spring 整合 ActiveMQ
1.1 JMS简介 JMS的全称是Java Message Service,即Java消息服务.它主要用于在生产者和消费者之间进行消息传递,生产者负责产生消息,而消费者负责接收消息.把它应用到 ...
- Spring整合JMS(一)——基于ActiveMQ实现
1.1 JMS简介 JMS的全称是Java Message Service,即Java消息服务.它主要用于在生产者和消费者之间进行消息传递,生产者负责产生消息,而消费者负责接收消息.把它应用到 ...
- Spring整合JMS-基于activeMQ实现(二)
Spring整合JMS-基于activeMQ实现(二) 1.消息监听器 在Spring整合JMS的应用中我们在定义消息监听器的时候一共能够定义三种类型的消息监听器,各自是MessageLis ...
- spring整合JMS - 基于ActiveMQ实现
一. 开篇语 继上一篇apache ActiveMQ之初体验后, 由于近期一直在复习spring的东西, 所以本文就使用spring整合下JMS. 二. 环境准备 1. ActiveMQ5.2.0 ( ...
随机推荐
- Elasticsearch由浅入深(七)搜索引擎:_search含义、_multi-index搜索模式、分页搜索以及深分页性能问题、query string search语法以及_all metadata原理
_search含义 _search查询返回结果数据含义分析 GET _search { , "timed_out": false, "_shards": { , ...
- 深入理解C语言 - 指针详解
一.什么是指针 C语言里,变量存放在内存中,而内存其实就是一组有序字节组成的数组,每个字节有唯一的内存地址.CPU 通过内存寻址对存储在内存中的某个指定数据对象的地址进行定位.这里,数据对象是指存储在 ...
- SQL -------- TOP 查询前几行
SELECT TOP 子句用于指定要返回的记录数量.并不是所有的数据库系统都支持SELECT TOP子句.MySQL支持LIMIT子句来选择有限数量的记录,而Oracle使用ROWNUM. top 后 ...
- Mysql 错误 ERROR 1 (HY000) at line 1: Can't create/write to file '/home/kaizenly/cfg_dict.csv' (Errcode: 13 - Permission denied)
[1]问题描述 (1)执行SQL语句: use billing; select * from cfg_dict into outfile '/home/kaizenly/cfg_dict.csv' f ...
- Linux常用命令:fdisk mkfs mount umount fstab实现自动挂载
写在前 记录点常用命令,fdisk mkfs mount和umount,以及fstab实现自动挂载 fdisk fdisk主要用于操作硬盘的分区表.分区,下面简单记一点最常用的部分 查看当前系统识别到 ...
- Git系列四之在本地服务器搭建gitlab仓库管理(centeros环境下)
1.Git仓库管理 现在本地已经创建了git仓库,又在gitlab上创建了一个git仓库,并且让这两个仓库进行远程同步,这样gitlab仓库既可以备份也可以与他人协作管理远程仓库以及根据需要推送或拉取 ...
- JavaIO学习:打印流
打印流 打印流是输出信息最方便的类,注意包含字节打印流:PrintStream和字符打印流:PrintWriter. 打印流提供了非常方便的打印功能,可以打印任何类型的数据信息,例如:小数,整数,字符 ...
- 很好的OpenCV入门资料
https://files.cnblogs.com/files/mqingqing123/OpenCV%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B.rar
- MarkDown 常用语法规则
> # 标题 # 标题1:h1的效果 ## 标题2:h2的效果 ### 标题3:h3的效果 #### 标题4:h4的效果 ##### 标题5:h5的效果 ###### 标题6:h6的效果 ### ...
- 基于Golang的逃逸分析(Language Mechanics On Escape Analysis)
何为逃逸分析 在编译程序优化理论中,逃逸分析是一种确定指针动态范围的方法——分析在程序的哪些地方可以访问到指针.它涉及到指针分析和形状分析. 当一个变量(或对象)在子程序中被分配时,一个指向变量的指针 ...