文章目录
【笔记于学习尚硅谷课程所作】
1、ActiveMQ概述
1.1 定义
是指利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。
通过提供消息传递和消息排队模型在分布式环境下提供应用解耦、弹性伸缩、冗余存储、流量削峰、异步通信、数据同步等功能
1.2 过程
发送者把消息发送给消息服务器,消息服务器将消息存放在若干队列/主题中,在合适的时候,消息服务器会将消息转发给接受者。
在这个过程中,发送和接受是异步的,也就是发送无需等待,而且发送者和接受者的生命周期也没有必然关系
尤其在发布pub/订阅sub模式下,也可以完成一对多的通信,即让一个消息有多个接受者。
1.3 特点与作用
- 异步通信
- 应用解耦
- 流量削峰
eg:
2、Linux环境下的安装
注:
后台:采用61616端口提供JMS服务
前端:采用8161端口提供管理控制台服务
1.官网下载 http://activemq.apache.org
2.解压安装
3.普通启动(在mq文件夹的bin目录下执行)
./activemq start
4.查看是否启动的三种方法
ps -ef|grep activemq
netstat -anp|grep 61616
lsof -i:61616
5.关闭
./activemq stop
6.[补充]带运行日志的启动方式
./activemq start>/myactivemq/run_activemq.log
7.apache activeMQ控制台[默认用户名密码是:admin/admin
http://localhost:8161
3、Java编码实现ActiveMQ通讯
3.1 了解JMS编码总体架构
3.2 粗说目的地Destination
1.两大模式特性
在点对点的消息传递域中,目的地被称为队列(queue)
在发布订阅消息传递域中,目的地被称为主题(topic)
2.两大模式比较
Topic模式 | Queue模式 | |
---|---|---|
工作模式 | “订阅发布“模式,如果当前没有订阅者,消息将会被丢弃.如果有多个订阅者,那么这些订阅者都会收到消息 | “负载均衡模式,如果当前没有消费者,消息也不会丢弃;如果有多个消费者,那么一条消息也只会发送始其中一个消费者, 并且要求消费者ack信息. |
有无状态 | 无状态 | Queue数据默认会在mq服务器上以文件形式保存,比如Active MQ一般保存在$AMQ_ HOME\data\kr- store\data下面。也可以配置成DB存储 |
传递完整性 | 如果没有订阅者,消息会被丢弃 | 消息不会丢弃 |
处理效率 | 由于消息要按照订阅者的数量进行复制,所以处理性能会随着订阅者的增加而明显降低,并且还要结合不同消息协议自身的性能差异 | 由于条消息只发送给个消费者,所以就算消费者再多,性能也不会有明显降低。当然不同消息协议的具体性能也是有差异的 |
3.3 JMS开发的基本步骤
- 创建一个connection factory
- 通过connection factory来创建JMS connection
- 启动JMS connection
- 通过connection创建JMS session
- 创建JMS destination
- 创建JMS producer或者创建JMS message并设置destination
- 创建JMS consumer或者是注册一个JMS message listener
- 发送或者接受JMS message(s)
- 关闭所有的JMS资源(connection, session, producer, consumer等)
3.4 两种消费方式
- 同步阻塞方式(receive):订阅者或接收者调用MessageConsumer的receive()方法来接收消息,receive 方法在能够接收到消息之前(或超时之前)将一直阻塞。
- 异步非阻塞方式(监听器onMessage():订阅者或接收者通过MessageConsumer的setMessageListener(MessageListener listener)注册一个消息监听器,当消息到达之后,系统自动调用监听器MessageListener的onMessage(Message message)方法。
3.5 生产者与消费者编码(队列)
1.项目需要导入的jar
<!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-all -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.15.12</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.xbean/xbean-spring -->
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-spring</artifactId>
<version>4.16</version>
</dependency>
2.生产者编码
public class JmsProduce{
public static final string ACTIVEMQ_URL="tcp://192.168.111.136:61616";
public static final string QUEUE_NAME="queue01";
public static void main(String[] args) throws JMSException{
//1、创建连按工厂,按照給定url地址,采用默认用户名和密码
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnection actory(ACTIVEMQ_URL);
//2、通过连接工厂,获得连接connection并启动访问
Connection connection = activeMQconnectionFactory.createConnection();
connection.start();
//3、创建会话session
//两个参数,第一个叫事务/第二个叫签收
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//4、创建目的地(具体是队列还是主题topic)
Queue queue = session.createQueue(QUEUE_NAME);
//5、创建消息的生产者
MessageProducer messageProducer = session.createProducer(queue);
//6、通过使用messageProducer生产3条消息发送到MQ的队列里面
for(inti=1;i<=3;i++){
//7、创建消息,好比学生按照阳哥的要求写好的面试题消息,
TextMessage textMessage = session.createTextMessage("msg---" + i);//理解为一个字符串
//8、通过messageProducer发送给mq
messageProducer.send(textMessage);
}
//9、关闭资源
messageProducer.close();
session.close();
connection.close();
System.out.println("*****消息发布到MQ完成");
}
}
3.消费者编码1
public class JmsComsumer{
public static final string ACTIVEMQ_URL="tcp://192.168.111.136:61616";
public static final string QUEUE_NAME="queue01";
public static void main(String[] args) throws JMSException{
//1、创建连按工厂,按照給定url地址,采用默认用户名和密码
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnection actory(ACTIVEMQ_URL);
//2通过连接工厂,获得连接connection并启动访问
Connection connection = activeMQconnectionFactory.createConnection();
connection.start();
//3创建会话session
//两个参数,第一个叫事务/第二个叫签收
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//4创建目的地(具体是队列还是主题topic)
Queue queue = session.createQueue(QUEUE_NAME);
//5创建消费者
MessageConsumer messageConsumer = session.createConsumer(queue);
while(true){
TextMessage textMessage = (TextMessage)messageConsumer.receive();
if(nu1ll != textMessage){
System.out.println("****消费者接收到消息: "+textMessage.getText());
}else{
break;
}
}
messageConsumer.close();
session.close();
connection.close();
}
}