-
今天分享一下消息中间件(消息队列)ActiveMQ过几天有空在总结一下RabbitMQ
为什么使用消息中间件?
-
在生活中,我们经常会在网上碰到一些比较奇怪的案例,比如,我们经常在注册用户的时候,网站常常
会给我们发送一封激活邮件,但是我们很久才能够收到这个邮件,我们在平常生活中进行一些支付的时
候,经常会发生的情况是我们支付成功以后,一直到晚上或者第二天的时候才能够收到这个短信。为什
么我们的信息不同步呢?没有实时的得到我们想要的结果。其实就是有消息中间件的存在。如果没有消息中间件,可能出现的问题是:
在互联网中有延迟或者网络原因的情况,这种情况我们如果
无法避免的话,意味着需要一直等待。当我们进行消费后,我们需要等到对方收到钱以后才能够离开,
可是可能已经到了第二天,这样的结果不是我们希望看到的。那么怎么解决这样的情况呢?
那么,在生活中如果遇到这样的情况,我们会找一个中间人,有对方做一个保障,那么所有的问题将会
完美的解决。而消息中间件正好在这充当这么一个角色。 -
消息中间件的应用场景
消息队列中间件是分布式系统中重要的组件
应用场景主要解决流量削锋,异步消息,应用解耦,消息通讯等问题,实现高性能,高可用和最终一致性架构。
流量削锋:
异步消息
应用解耦
消息通讯
常见的消息中间件产品
ActiveMQ java来用 实现了java的jsm规范 可以调用jms的接口代码去实现消息中间件的应用场景(只能用于JAVA)
RabbitMQ 阿里巴巴开源 (JAVA PHP 等都可以使用 也是当前最火的消息队列)
ZeroMQ
Kafka 大数据(日志处理kafka+storm)
今天主要说的就是 ActiveMQ 用于JAVA 好了 不废话 直接开始!
JMS消息服务规范
JMS(Java Messaging Service)是 Java 平台上有关面向消息中间件的技术规范
消息中间件是一种机制,而JMS是java实现消息中间件的手段(规范)
JMS 的消息模型(分两种)
point to point(p2p 点对点模型) ---点多点
pub/sub (发布订阅模型) ---点对多
点对点模型
Jms提供的规范Api(java代码的编写流程)
代码编写流程
消息队列 ActiveMQ
linux中安装
第一步:下载把 activemq的压缩包(apache-activemq-5.14.5-bin.tar.gz)上传到 linux 系统
第二步:解压缩压缩包
tar -zxvf apache-activemq-5.14.5-bin.tar.gz
第三步:进入apache-activemq-5.14.5的bin目录,创建data目录
cd apache-activemq-5.14.5/bin
第四步:启动 activemq
./activemq start
第五步:停止activemq:
./activemq stop
下面访问:
页面控制台: http://ip:8161 (监控) 可以监控生产者和消费者
请求地址: tcp://ip:61616 (java代码访问消息中间件)
入门小案例:
消息生产者
创建工程mq_producer
引入坐标Maven**
<dependencies>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-client</artifactId>
<version>5.13.4</version>
</dependency>
</dependencies>
编写生产消息的测试类MqProducerTest
**
public class MqProducerTest {
public static void main(String[] args) throws JMSException {
//1.创建连接工厂
ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://192.168.25.128:61616");
//2.创建连接
Connection connection = factory.createConnection();
//3.打开连接
connection.start();
//4.创建session
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//5.创建目标地址(Queue:点对点消息,Topic:发布订阅消息)
Queue queue = session.createQueue("hm105");
//6.创建消息生产者
MessageProducer producer = session.createProducer(queue);
//7.创建消息
TextMessage message = session.createTextMessage("不错");
//8.发送消息
producer.send(message);
session.close();;
connection.close();
}
}
消息消费者
创建工程mq_consumer
引入坐标**
和生产者依赖一致 (略)
编写消息消费的测试类MqConsumerTest
**
public class MqConsumerTest {
public static void main(String[] args) throws Exception {
//创建连接工长
ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://192.168.25.128:61616");
//创建连接
Connection connection = factory.createConnection();
//开启连接
connection.start();
//创建session
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//5.创建目标地址(Queue:点对点消息,Topic:发布订阅消息)
Queue queue = session.createQueue("hm105");
//6.创建消息的消费者
MessageConsumer consumer = session.createConsumer(queue);
//7.配置消息监听器
consumer.setMessageListener(new MessageListener() {
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println(textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
});
}
}
以上是单独的小案例
下面加入到spring中经行整合开发
消息生产者
创建工程Spring_mq_producer
引入坐标**
<properties>
<spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.11.2</version>
</dependency>
<dependency>
<groupId>javax.jms</groupId>
<artifactId>javax.jms-api</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
创建spring整合配置文件applicationContext-producer.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
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/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.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">
<!--
目的:spring和activeMq整合:通过整合JmsTemplate对象进行消息发送
-->
<!--1.连接工厂-->
<bean id="activeMQConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616"></property>
</bean>
<!--2.spring管理连接工厂-->
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory" ref="activeMQConnectionFactory"></property>
</bean>
<!--3.通过连接工厂创建jmstemplate-->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory"></property>
</bean>
<!--4.1 指定目的地址:queue-->
<bean id="queue" class="org.apache.activemq.command.ActiveMQQueue">
<!--名称-->
<constructor-arg value="xxx01"></constructor-arg>
</bean>
<!--4.2 指定目的地址:topic-->
<bean id="topic" class="org.apache.activemq.command.ActiveMQTopic">
<!--名称-->
<constructor-arg value="xxx02"></constructor-arg>
</bean>
<!--扫描工具类-->
<context:component-scan base-package="cn.itcast.utils"></context:component-scan>
</beans>
配置发送消息的工具类**
@Component
public class JmsTemplateUtils {
@Autowired
private JmsTemplate jmsTemplate;
@Autowired
private Destination queue;
@Autowired
private Destination topic;
// 发消息
public void send(final String value){
jmsTemplate.send(topic, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
TextMessage textMessage = session.createTextMessage(value);
return textMessage;
}
});
}
}
配置测试类MqProducerTest**
public class SpringProducer {
public static void main(String[] args) {
// 加载配置文件
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("classpath:applicationContext-jms.xml");
// 发送
JmsTemplateUtils jmsTemplateUtils =(JmsTemplateUtils)context.getBean("jmsTemplateUtils");
jmsTemplateUtils.send("点对点");
}
}
消息消费者
创建工程Spring_mq_consumer
引入坐标**
略
配置消息监听器cn.itcast.mq.QueueListener
**
// 点对点
public class QueueListener implements MessageListener{
@Override
public void onMessage(Message message) {
TextMessage textMessage=(TextMessage)message;
try {
System.out.println(textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
// 发布和订阅
public class TopicListener implements MessageListener{
@Override
public void onMessage(Message message) {
TextMessage textMessage=(TextMessage)message;
try {
System.out.println(textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
配置spring整合applicationContext-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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
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/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.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">
<!--1.连接工厂-->
<bean id="activeMQConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616"></property>
</bean>
<!--2.spring管理连接工厂-->
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory" ref="activeMQConnectionFactory"></property>
</bean>
<!--3.1 配置监听器管理器
配置是基于queue类型的消息监听用来监听点对点的消息
destination-type:指定类型
connection-factory:指定管理连接工厂
-->
<bean id="queueListener" class="cn.itcast.listener.QueueListener"></bean>
<jms:listener-container destination-type="queue" connection-factory="connectionFactory">
<jms:listener destination="xxx01" ref="queueListener"></jms:listener>
</jms:listener-container>
<!--3.1 配置监听器管理器
配置是基于topic类型的消息监听用来监听发布/订阅的消息
-->
<bean id="topicListener" class="cn.itcast.listener.TopicListener"></bean>
<jms:listener-container destination-type="topic" connection-factory="connectionFactory">
<jms:listener destination="xxx02" ref="topicListener"></jms:listener>
</jms:listener-container>
</beans>