什么时候使用mq
一、ActivityMq的介绍:
1.什么是消息中间件?与传统的传输通讯有什么区别?
异步,无需等待,消息存放在队列里面。
2.为什么要使用消息中间件?
消息中间件可以解决高并发。
两种通讯方式:01.点对点通讯。(Queue)
02.发布订阅。(Topic)
生产者:发送消息,提供接口的,主要向队列中发送消息
队列:存放消息地址
消息:发送的报文信息
消费者:调用接口的,主要从队列中获取消息
3.步骤:
01、生产者向队列进行发送消息,如果消费者不在,队列就会将消息缓存
02、消费者向队列中获取到消息之后,消费成功之后, 该消息队列直接被清除掉。(不清除就会产生重复消费问题)
4.生产者向队列中生产高并发流量,消费者会不会挂掉?
不会,因为队列会缓存消息。
5.为什么MQ能够解决高并发问题?
不会立马处理那么多的消息,队列会进行缓存,进行排队。
6.JMS:java发送消息,客户端与服务器进行通讯的方式,可以理解成java的消息 中间件
消息模型:
01、点对点通讯方式:
流程:生产者 队列 消费者。
特点:一对一 异步通讯,生产者生产的消息 只允许有一个消费者进行消费。
02、发布订阅:
流程:生产者 主题 消费者
特点:发布订阅 一个生产者 可以多个消费者 一对多。
二、ActivityMq安装:
1.下载ActivityMQ
官方网站:http://activemq.apache.org/download.html
2.运行ActivityMQ
解压apache-activemq-5.15.9-bin.zip,进入该文件夹的bin目录。
有两种方式启动ActivityMQ服务
01、在bin目录下用cmd命令activemq start 启动服务,关掉黑窗口服务即停止
02、进入bin目录下对应电脑位数的文件夹,64位进入win64,双击InstallService.bat批处理文件安装ActiveMQ服务,然后打开任务管理器启动ActiveMQ服务
启动服务后打开浏览器输入:http://localhost:8161/admin/ 输入默认设置的账户:admin密码admin
点击队列(Queues),输入队列名称(Queue Name)FirstQueue,然后点创建(Craete)
3.创建maven项目
添加一个activemq-all-5.15.3.jar即可,在pom.xml加入
<dependencies>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.15.3</version>
</dependency>
</dependencies>
三、创建producer.java和consumer.java
producer.java
package main;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Producer {
// 默认连接用户名
private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;
// 默认连接密码
private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;
// 默认连接地址
private static final String BROKER_URL = ActiveMQConnection.DEFAULT_BROKER_URL;
public static void main(String[] args) {
// 连接工厂
ConnectionFactory connectionFactory =
new ActiveMQConnectionFactory(USERNAME, PASSWORD, BROKER_URL);
try {
// 连接
Connection connection = connectionFactory.createConnection();
// 启动连接
connection.start();
// 创建session
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
// 消息目的地
Destination destination = session.createQueue("FirstQueue");
// 消息生产者
MessageProducer producer = session.createProducer(null);
// 设置不持久化,此处学习,实际根据项目决定
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
// 发送消息
for (int i = 0; i < 10; i++) {
// 创建一条文本消息
TextMessage message = session.createTextMessage("ActiveMQ: 这是第 " + i + " 条消息");
// Destination destination = session.createTopic("FirstQueueTopic");
// 生产者发送消息
producer.send(destination, message);
}
session.commit();
session.close();
connection.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
consumer.java
package main;
import javax.jms.*;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Consumer {
// 默认连接用户名
private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;
// 默认连接密码
private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;
// 默认连接地址
private static final String BROKER_URL = ActiveMQConnection.DEFAULT_BROKER_URL;
public static void main(String[] args) {
// 连接工厂
ConnectionFactory connectionFactory =
new ActiveMQConnectionFactory(USERNAME, PASSWORD, BROKER_URL);
try {
// 连接
Connection connection = connectionFactory.createConnection();
// 启动连接
connection.start();
// 创建session
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 消息目的地
Destination destination = session.createQueue("FirstQueue");
// Destination destination = session.createTopic("FirstQueueTopic");
// 消息消费者
MessageConsumer consumer = session.createConsumer(destination);
while (true) {
TextMessage message = (TextMessage) consumer.receive();
if (message != null) {
System.out.println("接收到消息: " + message.getText());
} else {
break;
}
}
session.close();
connection.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
四、测试:
先运行producer.java,再运行consumer.java。
五、项目中使用:
spring-activemq.xml配置文件:
生产者
<?xml version="1.0" encoding="UTF-8"?>
<!-- 查找最新的schemaLocation 访问 http://www.springframework.org/schema/ -->
<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:amq="http://activemq.apache.org/schema/core"
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
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd">
<amq:connectionFactory id="amqConnectionFactory"
brokerURL="${activemq.brokerURL}" userName="${activemq.username}" password="${activemq.password}" />
<bean id="connectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory">
<constructor-arg ref="amqConnectionFactory" />
<property name="sessionCacheSize" value="100" />
</bean>
<!-- 定义JmsTemplate的Queue类型 -->
<bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
<constructor-arg ref="connectionFactory" />
<!-- 非pub/sub模型(发布/订阅),即队列模式 -->
<property name="pubSubDomain" value="false" />
</bean>
<!-- 定义JmsTemplate的Topic类型 -->
<bean id="jmsTopicTemplate" class="org.springframework.jms.core.JmsTemplate">
<constructor-arg ref="connectionFactory" />
<!-- pub/sub模型(发布/订阅) -->
<property name="pubSubDomain" value="true" />
</bean>
</beans>
config.properties配置用户名,密码,url等信息。
activemq.brokerURL=failover:(tcp://10.135.100.59:9203,tcp://10.135.100.60:9203)
#activemq.brokerURL=tcp://10.135.100.59:9203
activemq.username=admin
activemq.password=admin
代码中的使用:
@Autowired
@Qualifier("jmsQueueTemplate")
private JmsTemplate jmsTemplate;// 通过@Qualifier修饰符来注入对应的bean
/**
* @Title: send 发送一条消息到指定的队列(目标)
* @Description:
* @param queueName 队列名称
* @param message 消息内容
* @date 2016年10月12日 上午10:15:56
*/
public void send(String queueName, final String message) {
jmsTemplate.send(queueName, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(message);
}
});
}