文章目录
一、关于MQ
1.什么是MQ
2.MQ的优势
1.应用解耦
2.异步提速
3.削峰填谷
3.MQ的劣势
4.使用MQ的条件
既然MQ有优势也有劣势,那么使用MQ需要满足什么条件呢?
- ①生产者不需要从消费者出获得反馈。A调用B只有不需要B做出反馈的时候才能使用MQ(因为订单系统一把消息给库存、支付、物流系统发出去就立马给用户做出反馈了,根本不等库存、支付、物流系统执行完了没有)。
- ②容许短暂的不一致性(因为订单系统一把消息给库存、支付、物流系统发出去就立马给用户做出反馈了,根本不等库存、支付、物流系统执行完了没有,这个时候是存在短暂的不一致的)。
- ③确实用了有效果。即解耦、提速、削峰这些方面的收益,超过加入MQ、管理MQ这些成本。
5.常见的MQ产品
二、关于RabbitMQ
1.关于RabbitMQ
- Broker:RabbitMQ server(RabbitMQ服务端)) 就是Message Broker
- Virtual Host:虚拟机,他就是逻辑分区,相当于MySQL里的数据库一样,就是逻辑分区
- Exchange:message到达broker的第一站,根据分发规则,配匹查询表中的routing key,分发消息到queue中去。常用的类型有:direct(point-to-point),topic(publish-subscribe)and fanout(multicast)
- Queue:消息最终被送到这里等待consumer取走
- Binding:exchange和queue之间的虚拟连接,binding中可以包含routing key。Binding信息被保存到exchange中的查询表中,用于message的分发依据。
2.RabbitMQ的6种工作模式
RabbitMQ的6种工作模式:简单模式、work queues、Publish/Subscribe发布与订阅模式、Routing路由模式、Topics主题模式、RPC程调用模式(远程调用,不太算MQ;暂不做介绍)。
3.JMS
- JMS即Java消息服务(JavaMessage Service)应用程序接口,是一个Java平台中关于面向消息中间件的API
- JMS是JavaEE规范中的一种,类比JDBC(官方没有提供JMS的实现包,但是开源社区有)
4.RabbitMQ的安装
学习视频:RabbitMQ的安装
安装在了“VirtualBox镜像克隆2”的master节点的/root目录下
RabbitMQ在安装好后,可以访问
http://ip地址:15672
;你访问192.168.56.103:15672
然后输入账号admin密码111111
5.RabbitMQ控制台的使用
学习视频:RabbitMQ控制台的使用
三、RabbitMQ快速入门
1.准备工作
2.创建生产者
运行程序后
2.消费者
注意,本截图有点问题,第五步“5.创建队列Queue”是没有必要存在的,消费者中没有必要再去创建那个名叫"hello_world"的队列了(当然,创建了也无法)
四、rabbitMQ的工作模式
1.简单模式(上面已学)
2.工作队列模式
1.创建并启动消费者
注意,本截图有点问题,第五步“5.创建队列Queue”是没有必要存在的,生产者已将创建了所以消费者中没有必要再去创建那个名叫"work_queues"的队列了(当然,创建了也无法)
2.创建并启动生产者
3.查看输出
3.PubSub订阅模式
1.生产者
程序运行后:
2.消费者
4.Routing路由模式
5.Topics通配符模式
五、Spring整合RabbitMQ
1.生产者端代码
1.资源文件rabbitmq.properties
rabbitmq.host=192.168.56.103
rabbitmq.port=5672
rabbitmq.username=heima
rabbitmq.password=111111
rabbitmq.virtual-host=/itcast
2.spring配置文件spring-rabbitmq-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:context="http://www.springframework.org/schema/context"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/rabbit
http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">
<!--加载配置文件-->
<context:property-placeholder location="classpath:rabbitmq.properties"/>
<!-- 定义连接工厂rabbitmq connectionFactory -->
<rabbit:connection-factory id="connectionFactory" host="${rabbitmq.host}"
port="${rabbitmq.port}"
username="${rabbitmq.username}"
password="${rabbitmq.password}"
virtual-host="${rabbitmq.virtual-host}"/>
<!--定义管理交换机、队列的admin工厂-->
<rabbit:admin connection-factory="connectionFactory"/>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~简单模式~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!--定义持久化队列,不存在则自动创建;不绑定到交换机则绑定到默认交换机
默认交换机类型为direct,名字为:"",路由键为队列的名称-->
<rabbit:queue id="spring_queue" name="spring_queue" auto-declare="true"/>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~广播模式~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!--定义广播交换机中的持久化队列,不存在则自动创建-->
<rabbit:queue id="spring_fanout_queue_1" name="spring_fanout_queue_1" auto-declare="true"/>
<!--定义广播交换机中的持久化队列,不存在则自动创建-->
<rabbit:queue id="spring_fanout_queue_2" name="spring_fanout_queue_2" auto-declare="true"/>
<!--定义广播类型交换机;并绑定上述两个队列-->
<rabbit:fanout-exchange id="spring_fanout_exchange" name="spring_fanout_exchange" auto-declare="true">
<rabbit:bindings>
<rabbit:binding queue="spring_fanout_queue_1"/>
<rabbit:binding queue="spring_fanout_queue_2"/>
</rabbit:bindings>
</rabbit:fanout-exchange>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~通配符模式;*匹配一个单词,#匹配多个单词 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!--定义广播交换机中的持久化队列,不存在则自动创建-->
<rabbit:queue id="spring_topic_queue_star" name="spring_topic_queue_star" auto-declare="true"/>
<!--定义广播交换机中的持久化队列,不存在则自动创建-->
<rabbit:queue id="spring_topic_queue_well" name="spring_topic_queue_well" auto-declare="true"/>
<!--定义广播交换机中的持久化队列,不存在则自动创建-->
<rabbit:queue id="spring_topic_queue_well2" name="spring_topic_queue_well2" auto-declare="true"/>
<!--定义交换机;并绑定上述三个队列-->
<rabbit:topic-exchange id="spring_topic_exchange" name="spring_topic_exchange" auto-declare="true">
<rabbit:bindings>
<rabbit:binding pattern="heima.*" queue="spring_topic_queue_star"/>
<rabbit:binding pattern="heima.#" queue="spring_topic_queue_well"/>
<rabbit:binding pattern="itcast.#" queue="spring_topic_queue_well2"/>
</rabbit:bindings>
</rabbit:topic-exchange>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~rabbitTemplate对象~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!--定义rabbitTemplate对象,简化代码-->
<rabbit:template id="rabbitTemplate" connection-factory="connectionFactory"/>
</beans>
3.测试文件ProducerTest.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-rabbitmq-producer.xml")
public class ProducerTest {
//1、注入RabbitTemplate
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void testHelloWorld(){
//2、发送消息(依次是队列id、消息)
rabbitTemplate.convertAndSend("spring_queue","hello world spring....");
}
@Test
public void testFanout(){
//2、发送消息(依次是交换机id、routingKey、消息)
rabbitTemplate.convertAndSend("spring_fanout_exchange","","spring fanout");
}
public void testTopic(){
//2、发送消息(依次是交换机id、routingKey、消息)
rabbitTemplate.convertAndSend("spring_topic_exchange","heima.hehe.haha","spring topics");
}
}
4.运行
5.原理
2.消费者端代码
1.资源文件rabbitmq.properties
rabbitmq.host=192.168.56.103
rabbitmq.port=5672
rabbitmq.username=heima
rabbitmq.password=111111
rabbitmq.virtual-host=/itcast
2.spring配置文件spring-rabbitmq-consumer.xml
3.监听类SpringQueueListener.java
public class SpringQueueListener implements MessageListener {
@Override
public void onMessage(Message message) {
//打印消息
System.out.println(new String(message.getBody()));
}
}
4.测试文件ConsumerTest.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-rabbitmq-consumer.xml")
public class ConsumerTest {
@Test
public void Test1(){
boolean flag = true;
while(flag){
//让它一直运行
}
}
}
5.运行