1. 基础activeMq信息介绍
(20条消息) ActiveMQ详解_一念成佛_LHY的博客-优快云博客_activemq
2.在linux中安装使用ActiveMq
(20条消息) Linux中安装ActiveMQ完整教程_ForFuture-优快云博客
3.课程地址和学习笔记及其思维导图
(20条消息) 消息中间件ActiveMQ课程笔记_aoeiuv的博客-优快云博客
4.尚硅谷周阳学习笔记
(21条消息) 尚硅谷—高级—MQ 之 ActiveMQ_周阳_张老师的博客-优快云博客_mq之activemq周阳
4.学习过程
注意:ActiveMq是基于java的一个消息中间件,所以得有java的相关配置
不同的服务器之间用ping来连接 ,ping得关上防火墙 ,查看本机的ip cmd: ipconfig
队列入门( queue 1对1)
两种消费方式:
1. 同步阻塞方式(receive())
订阅者或接收者调用MessageConsumer的receive()方法来接收消息,receive方法在能接 收到消息之前(或超时之前)将一直阻塞。
2.异步非阻塞方式(监听器onMessage())
订阅者或接收者调用MessageConsumer的setMessageListener(MessageListener listener) 注册一个消息监听器,当消息到之后,系统自动调用监听器MessageListener的onMessage (Message message)方法
点对点消息传递域的特点如下:
(1).每个消息只能有一个消费者,类似一对一的关系,好比个人快递自己领取自己的
(2).消息的生产者和消费者之家没有时间上的相关性,无论消费者在生产者发送消息的时候是否处于运行状态,消费者都可以提取消息,好比我们发送消息,发送者发送之后不见得接收者会立即查看
(3).消息被消费后队列中不会再被储存(出队列),所以消费者不会消费到已经被消费掉的消息
package com.zxy.example;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
import java.net.CookieHandler;
/**
* @author zxy
* @date 2021.11.14
* 发送消息
*/
public class JsmProduce {
/**
* 1. tcp://127.0.0.1:61616 127.0.0.1 本地的ip地址
* 2. 61616:是提供给Java程序连接的tcp端口。 8161 : 客户端的端口
* 3. 浏览器访问界面 http://localhost:8161/admin 地址是哪里开的activeMq 服务就访问哪里的地址
*/
public static final String ACTIVEMQ_URL = "tcp://127.0.0.1:61616";
public static final String QUEUE_NAME = "queue01";
// 主题 topic
public static final String TOPIC_NAME="topic01";
public static void main(String[] args) throws JMSException {
//1. 创建连接工厂,按照给定的url地址,采用默认用户名和密码
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();
//2.通过连接工厂,获取连接connection
Connection connection = activeMQConnectionFactory.createConnection();
connection.start();
//3. 创建会话 session
// 第一个参数:事务 第二个参数: 签收
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//4. 创建目的地(具体是队列还是主题topic)
/**
* 1.session.createTopic(topic_name);
* 2. Destination 是队列和主题所继承的父类
*/
Queue queue=session.createQueue(QUEUE_NAME);
// 主题 topic
Topic topic = session.createTopic(TOPIC_NAME);
//5. 创建消息的生产者 producer(生产者)
MessageProducer messageProducer = session.createProducer(queue);
// 主题 topic
MessageConsumer messageConsumer= session.createConsumer(topic);
//6. 通过使用messageProducer 生产三条消息发送到MQ的队列里
for(int i=1;i<=3;i++){
//7. 创建消息 (消息类型和接收的消息类型要一致)
TextMessage textMessage = session.createTextMessage("messageListener----" + i);//理解为一个字符串
//8. 通过messageProducer 发送给mq
messageProducer.send(textMessage);
}
messageProducer.close();
session.close();
connection.close();
System.out.println("******消息发布MQ完成");
}
}
package com.zxy.example;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
import java.io.IOException;
/**
* @author 赵兴宇
* @date 2021.11.15
* 消息中间件的消费者
*/
public class JmsConsumer {
public static final String ACTIVEMQ_URL = "tcp://127.0.0.1:61616";
public static final String QUEUE_NAME = "queue01";
//主题
public static final String TOPIC_NAME="topic01";
public static void main(String[] args) throws JMSException, IOException {
System.out.println("我是二号消费者");
//1. 创建连接工厂,按照给定的url地址,采用默认用户名和密码
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();
//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);
//创建主题topic
Topic topic = session.createTopic(TOPIC_NAME);
MessageConsumer messageConsumer= session.createConsumer(queue);
MessageProducer messageProducer = session.createProducer(topic);
/**
* 第一种方法:
* 1.两边的消息返回值类型要相同 TextMessage
* 2.receive 的参数是 多少毫秒过后收不到消息就断开程序(同步阻塞方式)
while (true){
TextMessage textMessage = (TextMessage) messageConsumer.receive(100L);
if(null != textMessage){
System.out.println("*********************消费者收到消息"+textMessage.getText());
}else{
break;
}
}
messageConsumer.close();
session.close();
connection.close();
*/
/**
* 第二种方式:
* 1.通过监听的方式来传递消息
* 2.
*/
messageConsumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
//需要判断是否传过来的是同一个类型
if(null != message && message instanceof TextMessage){
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("****消费者接受到消息:"+textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
});
/**
* 1.输入流System.in;
* read():
* 从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。
* 如果因为已经到达流末尾而没有可用的字节,则返回值 -1
* 在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。
* 2.在这里的作用是保证控制台不灭, 如果没有程序很快停止
* 3.键盘输入后则灭
*/
System.in.read();
messageConsumer.close();
session.close();
connection.close();
/**
* 1. 先启动 1号消费者, 在启动二号消费者
* 问题:2号消费者能消费吗?
* 答案: 不能 ,消息已经被一号消费完了
*
* 2. 先启动两个消费者,再生产六条消息,请问消费情况如何?
* 答案: 轮询的条数(负载均衡) ,一人一半(一人一条的来)
*/
}
}
主题入门(topic 1对多)
特点如下:
(1).生产者将消息发布到topic中,每个消息可以有多个消费者,属于1:n的关系
(2).生产者和消费者之间有时间上的相关性。订阅某个主题的消费者只能消费自它订阅之后发 布的消息*******(重点,未订阅之前的不会发送)代码如上(有topic的地方,与队列略微不同)
(3).生产者生产时,topic不保存消息它是无状态的不落地,假如无人订阅就去生产,那就是一条无用的消息,所以一般先启动消费者再启动生产者。
(4),topic的代码如上,只有少数代码被改动