activemq rabbitmq
一.ActiveMQ
1.什么是消息队列
ActiveMQ是Apache出品,最流行的,能力强劲的开源消息总线。
消息队列是在消息的传输过程中保存消息的容器
2.介绍RabbitMQ与ActiveMQ
ActiveMQ 是 Apache 出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完 全支持 JMS1.1 和 J2EE 1.4 规范的 JMS Provider 实现。
RabbitMQ RabbitMQ 是一个在 AMQP 基础上完成的,可复用的企业消息系统。他遵循 Mozilla Public License 开源协议。开发语言为 Erlang。
3.消息队列的应用场景
消息队列的主要特点是异步处理,主要目的是减少请求响应时间和解耦。所以主要的使 用场景就是将比较耗时而且不需要即时(同步)返回结果的操作作为消息放入消息队列。同 时由于使用了消息队列,只要保证消息格式不变,消息的发送方和接收方并不需要彼此联系, 也不需要受对方的影响,即解耦和。 流量的削峰
4.JMS
ActiveMQ用JMS模型
JMS(Java Messaging Service)是 Java 平台上有关面向消息中间件的技术规范,它便于 消息系统中的 Java 应用程序进行消息交换,并且通过提供标准的产生、发送、接收消息的接 口,简化企业应用的开发。
JMS模型
点对点模型:生产者发送一条消息到 queue,只有一个消费者能收到。
发布订阅模型:发布者发送到 topic 的消息,只有订阅了 topic 的订阅者才会收到消息
5.spring整合ActiveMQ
5.1 创建 spring-activemq-producer
5.1.1 修改pom文件
<!-- ActiveMQ 客户端完整 jar 包依赖 -->
<dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-all</artifactId> </dependency> <!-- ActiveMQ 和 Spring 整合配置文件标签处理 jar包依赖 --> <dependency> <groupId>org.apache.xbean</groupId> <artifactId>xbean-spring</artifactId> </dependency> <!-- Spring-JMS 插件相关 jar 包依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> </dependency>
|
5.1.2整合 ActiveMQ
<!-- amq:connectionFactory 是 bean 标签的子标签,会在 spring 容器中创建一个 bean 对象.可以为对象命名. 类似: <bean id="" class="ActiveMQConnectionFactory"></bean>--> <amq:connectionFactory brokerURL="tcp://192.168.70.151:61616" userName="admin" password="admin" id="amqConnectionFactory"/> <!-- spring 管理 JMS 相关代码的时候,必须依赖 jms 标签库. spring-jms 提供的标签库. --> <!-- 定义 Spring-JMS 中的连接工厂对象CachingConnectionFactory - spring 框架提供的连接工厂对象. 不能真正的访问 MOM 容器. 类似一个工厂的代理对象. 需要提供一个真实工厂,实现 MOM 容器的连接访问.--> <bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactoryBean"> <property name="connectionFactory" ref="amqConnectionFactory"></property> <property name="maxConnections" value="10"></property> </bean> <!-- 配置有缓存的 ConnectionFactory,session 的缓存大小可定制。 --> <bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory"> <property name="targetConnectionFactory" ref="pooledConnectionFactory"></property> <property name="sessionCacheSize" value="3"></property> </bean> <!-- JmsTemplate 配置 --> <bean id="template" class="org.springframework.jms.core.JmsTemplate"> <!-- 给定连接工厂, 必须是 spring 创建的连接工厂. --> <property name="connectionFactory" ref="connectionFactory"></property> <!-- 可选 - 默认目的地命名 --> <property name="defaultDestinationName" value="test-spring"></property> </bean>
|
5.2 创建 spring-activemq-consumer
5.2.1 修改pom文件
同上
5.2.2 整合ActiveMQ
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory"> <property name="targetConnectionFactory" ref="amqConnectionFactory"></property> <property name="sessionCacheSize" value="3"></property> </bean> <!-- 注册监听器 --> <jms:listener-container acknowledge="auto" container-type="default" destination-type="queue" connection-factory="connectionFactory" > <!-- 在监听器容器中注册某监听器对象.destination - 设置目的地命名ref - 指定监听器对象--> <jms:listener destination="test-spring" ref="myListener"/> </jms:listener-container>
|
5.3 测试整合
5 .3.1Producer 发送消息
如果使用了连接池需要添加两个坐标
<dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-pool</artifactId> <version>5.9.0</version> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-jms-pool</artifactId> <version>5.9.0</version> </dependency>
|
5.3.2 发送消息
@Service public class UserServiceImpl implements UserService { @Autowired private JmsTemplate jmsTemplate; @Override public void addUser(final Users user) { //发送消息 this.jmsTemplate.send(new MessageCreator(){ @Override public Message createMessage(Session session) throws JMSException { Message message =session.createObjectMessage(user); return message; } }); } }
|
5.3.3 Consumer 接收消息
@Component(value="myListener") public class MyMessageListener implements MessageListener{ @Autowired private UserService userService; @Override public void onMessage(Message message) { //处理消息 ObjectMessage objMessage =(ObjectMessage)message; Users user=null; try { user = (Users)objMessage.getObject(); } catch (JMSException e) { // TODO Auto-generated catch block e.printStackTrace(); } this.userService.showUser(user); } }
|
二.RabbitMQ 原理图
1.RabbitMQ 原理图
消息的生产者发送消息到交换器,交换器将这些消息路由给服务器中的队列,等待消费者连接到这个队列将其取走。队列和消费者之间通过信道连接,是Tcp里面的虚拟连接。
2.Rabbit 交换器
2,1 Direct 交换器(发布与订阅 完全匹配)
2.2 Topic 交换器(主题,规则匹配)
2.3 Fanout 交换器(广播)
3.RabbitMQ 的消息持久化处理
消息确认ACK?
如果在处理消息的过程中,消费者的服务器在处理消息时出现异常,那可能正在处理的消息就没有完成消息的消费,数就会丢失,为了确保数据不会丢失,RabbitMQ支持消息确认机制-ACK
ACK机制是消费者从RabbitMQ收到消息并处理完成后,反馈给RabbitMQ,RabbitMQ收到反馈后才将此消息从队列中删除。