1.今日内容
1.Rabbitmq介绍
2.Rabbitmq优势以及劣势介绍
3.Rabbitmq架构
4.Rabbitmq管控台介绍
5.Rabbitmq五种发送消息的模式代码实现
一 RabbitMq介绍
Rabbit Mq ——》 Message Queue : 消息队列
队列特点:先进先出
生产者:发送消息方称为是生产者,谁生产消息谁就是生产者
消费者:监听消息(队列),监听到后拉取下来进行消费,称为是消费者
二 Rabbitmq优劣势
1. 优势
-
应用解耦
生产者和消费者之间进行了应用的解耦
-
异步提速
使用前提是系统为异步调用系统
- 削峰填谷
通过削峰填谷保证系统的稳定性
2. 劣势
- 系统稳定性下降
- 数据一致性问题
- 消息丢失---->消息确认
- 消息重复---->消息幂等性问题
- …
3. 使用场景
- 系统必须支持异步通信
三 MQ常见产品
- RabbitMq
- 使用erlang语言进行开发,效率高,吞吐量很大
- 属于rabbit公司
- RocketMq
- 使用java开发,脱胎于kafka(来源、模仿)
- 属于阿里,目前已经捐献给apache,称为了顶级项目
- ActiveMQ
- 是一款很古老的mq,目前使用的较少
- 属于apache
- Kafka
- 属于apache
- 用于大数据环境使用
四 Rabbitmq架构
注意事项:
- Exchange交换机不具备保存消息的功能,需要与队列完成绑定
- 绑定后符合规则的消息会路由至队列进行保存,不符合路由规则的消息或者是没有绑定队列的交换机消息会丢失
五 Rabbitmq管控台介绍
六 Rabbitmq五种发送消息的模式代码实现
https://www.rabbitmq.com/getstarted.html
1. 简单模式(hello world)
步骤:
-
创建项目
- web/lombok/rabbitmq
-
编写配置文件
-
#mq配置 spring: rabbitmq: host: 192.168.200.132
-
-
创建队列----》Java Bean
import org.springframework.amqp.core.Queue; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration //声明是一个配置类 public class QueueConfig { /** * @Author: guodong * @Date: 11:33 2020/9/26 * @Parms [] * @ReturnType: org.springframework.amqp.core.Queue * @Description: 创建itheima-31队列 */ @Bean public Queue queue(){ return new Queue("itheima-31"); } }
-
创建生产者发送消息
@RestController @RequestMapping("hello") @Slf4j public class HelloController { @Autowired private RabbitTemplate rabbitTemplate; @GetMapping("sendMsg/{msg}") public void sendMsg(@PathVariable String msg){ /* 第一个参数是routingkey: 路由键,默认是队列名称 第二个参数是发送的消息 */ rabbitTemplate.convertAndSend("itheima-31", msg); log.info("发送消息完毕 : {}" , msg); } }
-
创建消费者监听消息
@RabbitListener(queues = "itheima-31") //声明监听的消息队列 @Slf4j @Component public class ConsumerListener { @RabbitHandler //转换消息 public void receiveMsg(String msg){ log.info("消费者接收到消息: {}" , msg); } }
2. 工作队列模式(work queue)
步骤:
- 复制粘贴,需要修改日志输出,以便查看是那个消费者接收到消息
小结:
- 工作队列模式特点:
- 消费者之间是竞争关系
- 消费者之间会进行轮训接收消息
- 以上两种模式共有的特点是不需要声明交换机,但是使用的是默认的交换机。
3. 发布订阅模式
- Fanout(广播类型交换机)
步骤:
- 创建fanout类型交换机
- 创建fanout.A、fanout.B、fanout.C
- 完成三个队列与交换机的绑定
- 发送消息
- 编写三个消费者
代码实现:
-
创建队列+交换机并且完成绑定
/** * @Author: guodong * @Date: 12:06 2020/9/26 * @Parms [] * @ReturnType: org.springframework.amqp.core.FanoutExchange * @Description: 创建fanout类型交换机 */ @Bean public FanoutExchange fanoutExchange(){ return new FanoutExchange("itheihei"); } /* bean在创建时默认的bean name是方法名 */ @Bean public Queue fanoutA(){ return new Queue("fanout.A"); } @Bean public Queue fanoutB(){ return new Queue("fanout.B"); } @Bean public Queue fanoutC(){ return new Queue("fanout.C"); } /* 交换机与队列完成绑定 */ @Bean public Binding bindFanoutA(FanoutExchange fanoutExchange, Queue fanoutA){ return BindingBuilder.bind(fanoutA).to(fanoutExchange); } @Bean public Binding bindFanoutB(FanoutExchange fanoutExchange, Queue fanoutB){ return BindingBuilder.bind(fanoutB).to(fanoutExchange); } @Bean public Binding bindFanoutC(FanoutExchange fanoutExchange, Queue fanoutC){ return BindingBuilder.bind(fanoutC).to(fanoutExchange); }
-
发送消息
@GetMapping("sendMsgEx/{msg}") public void sendMsgEx(@PathVariable String msg){ /* 第一个参数是routingkey: 路由键,默认是队列名称 第二个参数是发送的消息 */ rabbitTemplate.convertAndSend("itheihei", "", msg); log.info("发送广播类型消息完毕 : {}" , msg); }
-
接收消息
@RabbitListener(queues = "fanout.A") //声明监听的消息队列 @Slf4j @Component public class FanoutListenerA { @RabbitHandler //转换消息 public void receiveMsg(String msg){ log.info("fanoutA 接收到消息: {}" , msg); } }
小结:
-
广播类型消息特点:
- 需要声明fanout类型交换机
- 需要完成交换机与队列的绑定
- 发送的消息可以被所有完成绑定的队列接收到,形成广播类型的消息
-
Direct(路由键模式/点对点模式)
步骤:
- 创建交换机
- 创建队列
- 完成队列与交换机的绑定并且设置路由键
小结:
-
direct模式的特点:
- 需要声明direct类型的交换机
- 完成队列与交换机的绑定并且需要设置路由键
- 在发送消息时需要指定路由键,只有符合规则(完全匹配)的路由键才可以将消息从交换机路由至队列,
- 如上图所示如果routingKey为itheima则A和B全部可以接收到消息,如果routingKey为itcast则只有B队列可以接收到消息
-
Topic(主题模式/通配符模式)
步骤:
- 创建交换机
- 创建队列
- 完成队列与交换机的绑定并且设置路由键
小结:
- topic模式特点:
- 需要声明direct类型的交换机
- 完成队列与交换机的绑定并且需要设置路由键
- 在发送消息时需要指定路由键,只有符合规则才会路由至队列
- 规则:
- “*” : 不多不少正好匹配一个词
- “#”: 匹配大于等于0个词
- 究竟有多少个词是用 "."来判断的
- 上图所示的案例中并且必须以itheima作为第一个词存在