文章目录
1. MQ基本概念
1.1概述
MQ全称Message Queue 消息队列 ,是在消息传输过程中保存消息的容器。多用于分布式系统之间进行通信。
1.远程调用 2.通过mq间接通信
1.2 MQ的优势和劣势
优势:
- 应用解耦
- 异步提速
- 削峰填谷
劣势:
- 系统可用性降低
- 系统复杂度提高
- 一致性问题
1.3 优势
应用解耦
- 问题:通过远程调用的方式,系统的耦合性会有所增加,容错率就会变低,可维护性就越低。
- 解决方案:使用mq消息中间件
- 好处:降低系统的耦合性,提高容错


使用MQ让应用之间解耦,提升容错性和可维护性
异步提速
-
问题:同步操作,下单耗时太长
-
解决方案:直接用mq响应用户请求
-
好处:能够提升用户体验和系统吞吐量(单位时间内处理请求的数目)


削峰填谷
问题:由用户直接访问系统,系统的并发量不稳定并且容易宕机
解决方案:mq处理高并发。系统通过mq,拉取消息
好处:系统并发稳定,不易宕机


1.4 MQ的劣势
系统可用性降低
场景:中间件存在
结果:系统的可用性降低
分析:系统引入的外部依赖越多,系统稳定性越差。一旦MQ宕机,就会对业务造成影响。
问题:如何保证MQ 可用性?
系统复杂度提高
场景:消息中间件
结果
分析:MQ加入增加了系统复杂度,以前系统间是同步的远程调用,现在是通过MQ进行异步调用。
问题:如何保证消息没有被重复消费?怎么处理消息丢失的情况?如何保证消息传递的顺序性?
一致性问题
场景:A系统处理完业务,通过MQ给B、C、D三个系统发消息,如果B系统、C系统处理成功,D系统处理失败。
问题:消息不一致?
小结
MQ需要满足什么条件?
- 生产者不需要从消费者获得反馈。引入消息队列之前的直接调用,其接口的返回值应该为空,这才让明白下层的动作没有进行,上层却认为动作已经完成继续往后走,即异步成为可能。
- 容许消息短暂的不一致性
- 确实是用了有效果。即收益超过成本和风险
1.5 常见的MQ产品
Erlang:专门适用于高并发场景
Scala:JVM使用语言
消息延迟与语言的关系?
1.6 RabbitMQ 简介
AMQP,即 Advanced Message Queuin Protocol (高级消息队列协议),是一个网络协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同开发语言的限制。

RrabbitMQ 基础架构如图:

- Broker:接收和分发消息的应用,RabbitMQ Server就是 Message Broker
- Virtual host :出于多租户和安全因素设计的,把AMQP的基本组件划分到一个虚拟的分组中,类似于网络中namespace 概念。当多个不同的用户使用同一个server提供的服务时,可以划分出多个vhost,每个用户在自己的vhost创建 exchange/queue 等
- Connection:publisher/consumer和broker之间的TCP连接
- Channel:如果每一次访问RabbitMQ都建立一个Connection,在消息两大的时候建立TCP Connetion的开销都是巨大的,效率也较低。Channel是在connetion 内部建立的逻辑连接,如果应用程序支持多线程,通常每个thread创建单独的channel进行通讯,AMQP method 包含了 channel id 帮助客户端和message broker 识别 channel ,所以 channel 之间是完全隔离的。Channel 作为轻量级的 Connection 极大减少了操作系统建立TCP connection的开销。
- Exchange:message 到达broker的第一站,根据分发规则,匹配查询表中的routing key,分发消息到queue中去。常用的类型有:direct(point-to-point),topic(publish-subscribe)and fanout(multicast)
- Queue:消息最终被送到这里等待consumer取走
- Binding:exchange和queue之间的虚拟连接,bingding中可以包含routing key 。Binding 信息被保存到exchange查询表中,用于message的分发依据。
RabbitMQ 提供了6种工作模式:

1.7 JMS
- JMS即Java消息服务(JavaMessage Service)应用程序接口,是一个Java平台中关于面向消息中间件的API
- 类比JDBC
- 很多消息中间件都实现了JMS规范,但不一定提供了实现,可以在开源社区找
1.8 小结

2. RabbitMQ 常用命令和使用
rabbitmq常用操作
rabbitmq管理台使用
3.RabbitMQ程序实现
3.1步骤
3.1.1 生产者代码
1.创建模块
- consumer 和 producer
2.导入Maven依赖
3.完成两个模块的代码

- producer 发送消息
- 1.创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
- 2.设置参数
factory.setHost("192.168.92.128");
factory.setPort(5672);
factory.setVirtualHost("/itqxy");
factory.setUsername("qxy");
factory.setPassword("qxy");
- 3.创建连接 connection
Connection connection = factory.newConnection(); - 4.创建频道 channel
Channel channel = connection.createChannel();
- 5.创建队列
/*
queueDeclare();
参数:
1.queue:队列名称
2.durable:是否持久化,当mq重启之后,还在
3.exclusive:
*是否独占。只能有一个消费者监听这队列
*当Connection关闭时,是否删除队列
4.autoDelete:是否自动删除。当没有Consumer时,自动删除掉
5.arguments:参数。
*/
channel.queueDeclare()
channel.basicPublish()
- 6.发送消息

3.1.2 消费者代码
与生产者不同的是,channel的方法不同
4.RabbitMQ的工作模式
4.1 Work queues 工作队列模式
- Work Queues :与入门程序的简单模式相比,多了一个或一些消费端,多个消费端共同消费同一个队列中的消息
- 应用场景:任务较多
4.2 Pub/Sub 订阅模式

-
轮询分发 :使用任务队列的优点之一就是可以轻易的并行工作。如果我们积压了好多工作,我们可以通过增加工作者(消费者)来解决这一问题,使得系统的伸缩性更加容易。在默认情况下,RabbitMQ将逐个发送消息到在序列中的下一个消费者(而不考虑每个任务的时长等等,且是提前一次性分配,并非一个一个分配)。平均每个消费者获得相同数量的消息。这种方式分发消息机制称为Round-Robin(轮询)。
-
公平分发 :虽然上面的分配法方式也还行,但是有个问题就是:比如:现在有2个消费者,所有的奇数的消息都是繁忙的,而偶数则是轻松的。按照轮询的方式,奇数的任务交给了第一个消费者,所以一直在忙个不停。偶数的任务交给另一个消费者,则立即完成任务,然后闲得不行。而RabbitMQ则是不了解这些的。这是因为当消息进入队列,RabbitMQ就会分派消息。它不看消费者为应答的数目,只是盲目的将消息发给轮询指定的消费者。
4.3 路由模式


4.4 主题模式(通配符模式)


3663

被折叠的 条评论
为什么被折叠?



