消息队列MQ简介
消息队列技术是分布式应用间交换信息的一种技术。使用消息队列可以很好的将任务以异步的方式进行处理或者进行数据传送和储存等。例如当你频繁地向数据库中插入数据、频繁的向搜索引擎提交数据,就可采取消息队列来异步插入。另外,还可以将较慢/较复杂的处理逻辑、有并发数量限制的处理逻辑,通过消息队列放在后台处理。
常规的使用场景:短信服务、电子邮件服务、图片处理服务、好友动态推送服务等。
特性:异步、顺序读写、高性能、协议简单。所以一般会用于解决大量的服务器端异步请求,同时可以实现服务端的负载均衡和业务的容灾
- 消息模型: 点对点(p2p)、发布/广播(Pub/Sub)。
- 流程:
p2p:消息生产者>消息队列>消息消费者
Pub/Sub:主题>发布者>订阅者
apache官网下载activeMQ:http://activemq.apache.org/download.html
- ActiveMQ准备
- 进行解压后运行其bin目录下面的win32或者win64文件夹下的activemq.bat文件启动activeMQ。
Maven配置
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>4.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.7.0</version>
</dependency>
!
配置connectionFactory
connectionFactory是Spring用于创建到JMS服务器链接的,Spring提供了多种connectionFactory.
PooledConnectionFactory: JmsTemlate每次发送消息时只会缓存connection,session和productor,不会缓存consumer。因此只适合于生产者发送消息,这个只是在要求消息处理的及时性不是特别高的情况下。
SingleConnectionFactory: 对于建立JMS服务器链接的请求会一直返回同一个链接,并且会忽略Connection的close方法调用。
CachingConnectionFactory: 继承了SingleConnectionFactory,所以它拥有SingleConnectionFactory的所有功能,同时它还新增了缓存功能,它可以缓存Session、MessageProducer和MessageConsumer。我们使用CachingConnectionFactory来作为示例。
applicationContext.xml 设置:
<!-- 获取ActiveMQ提供的ConnectionFactory -->
<amq:connectionFactory id="amqConnectionFactory"
<!--设置ActiveMQ服务器地址及端口-->
brokerURL="failover:(tcp://localhost:61616)?initialReconnectDelay=100" />
<!-- 配置ActiveMQ服务器连接conneciotnFactory -->
<bean id="connectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory">
<!-- 将ActiveMQ提供的ConnectionFactory注入到Spring管理的connectionFactory中 -->
<constructor-arg ref="amqConnectionFactory" />
<!--设置缓存大小-->
<property name="sessionCacheSize" value="100" />
</bean>
<!-- 配置JMS消息生产者 -->
<!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->
<bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
<constructor-arg ref="connectionFactory" />
<!-- 非pub/sub模型(发布/订阅),即队列模式 -->
<property name="pubSubDomain" value="false" />
</bean>
<!-- 定义Queue监听器 -->
<jms:listener-container concurrency="10"
destination-type="queue" container-type="default" connection-factory="connectionFactory" acknowledge="auto">
<!--监听的java类-->
<jms:listener destination="queue" ref="ConsumerMessageListener" />
</jms:listener-container>
@Service("ProducerService")
public class ProducerServiceImpl{
@Autowired
private JmsTemplate jmsQueueTemplate;
public void sendMessage(String destinationName, final String message) {
System.out.println("------生产者发送消息------");
System.out.println("------生产者发了一个消息:" + message);
jmsQueueTemplate.send(destinationName, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
// TODO Auto-generated method stub
return session.createTextMessage(message);
}
});
}
}
实现消息监听,获取消息并消费
@Component("ConsumerMessageListener")
public class ConsumerMessageListener implements MessageListener {
public void onMessage(Message message) {
// TODO Auto-generated method stub
TextMessage textMsg = (TextMessage) message;
System.out.println("接收到一个纯文本消息.");
try {
System.out.println("消息内容是:" + textMsg.getText());
} catch (Exception e) {
e.printStackTrace();
}
}
}