单词
Event-事件、topic-主题 、queue-队列、destination-目的地 、 producer-生产者 、broker-中间商 、send-发送 、
receive-接收、deliver-交付、persistent、持久化、embed-嵌入、delay-延迟、period-周期、repeat-重复
前言
MQ = 消息中间件
通过提供消息传递和消息排队模型在分布式环境下提供应用解耦、弹性伸缩、冗余存储、流量削峰、异步通信、数据同步等功能。
-
为什么要引入MQ ?
解耦,消峰,异步
解决了耦合调用的问题
异步模型
抵御了洪峰流量,达到保护主业务的目的,消峰
队列(queue):一对一,异步
主题(topic):一对多,一个消息有多个接受者
安装、运行
安装
解压缩到 linux 下的opt
运用
-
./activemq start 运行
-
./activemq stop 停止
activeMQ 默认(后台)端口号:61616 (提供JMS服务(JMS : JAVA消息服务))
前台端口号:8161 (提供管理控制台服务)
连接前台需要关闭linux和windows的防火墙
如果前台无法连接8161端口
修改conf/jetty.xml文件,把127.0.0.1修改成0.0.0.0,然后重启,这样解决了访问问题。
- activemq的默认用户名和密码:admin & admin
队列与主题
在点对点的消息传递域中,目的地被称为队列(queue)
在发布订阅消息传递域中,目的地被称为主题(topic)
消息生产者编码 (queue)
activeMQ 形参中有一个值brokerURL
brokerURL : active的地址 以tcp:// 开头
brokerURL tcp:// ip地址:端口61616
public class JmsProducer {
// Activemq的连接地址 , 不要用硬编码
public static final String ACTIVEMQ_URL = "tcp://192.168.177.130:61616";
// 创建一个队列名字
public static final String QUEUE_NAME = "queue01";
public static void main(String[] args) throws Exception {
//1、 获取连接工厂
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
// 2、获取连接并运行
Connection connection = activeMQConnectionFactory.createConnection();
connection.start();
// 3、 获取session 两个参数,事务/签收
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 4、 创建目的地,具体是队列(queue)还是主题(topic)可以用返回值表示
Queue queue = session.createQueue(QUEUE_NAME);
// 5、 创建消息的生产者 , 生产者创建信息,把信息放到哪里?(队列中)
MessageProducer producer = session.createProducer(queue);
for (int i = 0; i < 3; i++) {
// 6、 创建信息
TextMessage textMessage = session.createTextMessage("message--->" + i );
// 7、 通过MessageProducer发送给MQ
producer.send(textMessage);
}
// 8、 关闭连接
producer.close();
session.close();
connection.close();
System.out.println("------完成--------");
}
}
消费者编码 (queue)
- 同步阻塞方法:订阅者或接受者调用MessageConsumer的recerve()方法类接收消息,receive方法在能够接收到消息之前(或超时之前)将一直阻塞
public class JmsConsumer {
public static final String ACTIVEMQ_URL = "tcp://192.168.177.130:61616";
public static final String QUEUE_NAME = "queue01";
public static void main(String[] args) throws JMSException {
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
Connection connection = activeMQConnectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue(QUEUE_NAME);
// 接收的队列名需要与生产者队列名一致
MessageConsumer consumer = session.createConsumer(queue);
// 接收多条消息,一直接收
while (true) {
// 强制转换,接收什么类型,就转化成什么类型
// receive() 一直等待,直到接收到消息为止,receive(Timeout) 设定时间(毫秒单位),多久接收不到消息就不在等待
TextMessage textMessage = (TextMessage) consumer.receive();
if (textMessage != null) {
System.out.println(textMessage.getText());
} else {
break;
}
}
consumer.close();
session.close();
connection.close();
}
}
- 异步非阻塞方式:订阅者或接受者通过MessageConsumer的serMessageListener(MessageListener listener)注册一个消息监听器,当消息到达之后,系统自动调用监听器MessageListener的onMessage(Message message)方法
public class JmsConsumer2 {
public static final String ACTIVEMQ_URL = "tcp://192.168.177.130:61616";
public static final String QUEUE_NAME = "queue01";
public static void main(String[] args) throws JMSException, IOException {
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
Connection connection = activeMQConnectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue(QUEUE_NAME);
MessageConsumer consumer = session.createConsumer(queue);
// 消息监听器
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
if(message != null && message instanceof TextMessage){
TextMessage textMessage = (TextMessage) message;
try {
System.out.println(textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
});
// 让控制台不灭,一直等待,消息监听需要时间
System.in.read();
consumer.close();·
session.close();
connection.close();
}
}
消息生产者编码(topic)
类似微信公众号的订阅发布
public class JmsProducer_topic {
public static final String ACTIVEMQ_URL = "tcp://192.168.177.130:61616";
public static final String TOPIC_NAME = "topic01";
public static void main(String[] args) throws JMSException {
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
Connection connection = activeMQConnectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 主题
Topic topic = session.createTopic(TOPIC_NAME);
MessageProducer producer = session.createProducer(topic);
for (int i = 1; i <= 3; i++) {
TextMessage textMessage = session.createTextMessage("TOPIC 消息 -->" + i );
producer.send(textMessage);
}
producer.close();
session.close();
connection.close();
System.out.println