什么是MQMQ全称是Message Queue,消息的队列,因为是队列,所以遵循FIFO 先进先出的原则,它是一种跨进程的通信机制,用于上下游传递消息。在互联网架构中,MQ是一种非常常见的上下游“逻辑解耦+物理解耦”的消息通信服务。 为什么使用MQ①流量削峰:解决高并发问题 例如秒杀活动,可能会在短时间内产生大量请求同时打到服务端,如果后端对每个请求都进行数据库读写操作,定会造成服务器压力过大,产生服务异常甚至不可用。我们可以通过使用MQ实现流量缓冲,将所有请求先放入消息队列中,服务端每次处理业务先从消息队列获取,从而实现流量削峰,解决高并发问题。 ②应用解耦:提升系统可用性 例如电商应用中有订单系统、库存系统、物流系统、支付系统,当用户创建订单后,先后调用库存系统、物流系统、支付系统,任何一个子系统出了故障,都会造成下单失败。引入消息队列后,系统间耦合调用的问题会减少,任何一个子系统出现故障都不会影响用户下单,子系统故障恢复后,会继续处理消息,提升系统可用性。 ③异步处理:提升响应速度 当用户在客户端提交了一个同步请求,后端处理需要耗时很久才能响应,这对用户体验来说无疑是致命的。如果说用户并不关心请求是否处理完成,对于一些耗时的非事务性的业务处理,可以使用消息队列异步请求的方式,将请求信息放入消息队列,直接返回客户端响应,后端监听队列自行处理,提升响应速度。 常见MQ分类①Kafka 号称大数据的杀手锏,谈到大数据领域内的消息传输,则绕不开Kafka,这款为大数据而生的消息中间件,以其百万级TPS的吞吐量名声大噪,迅速成为大数据领域的宠儿,在数据采集、传输、存储的过程中发挥着举足轻重的作用。 优点:单机写入TPS约在百万条/秒,最大的优点,就是吞吐量高。时效性ms级可用性非常高,kafka是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用,消费者采用Pull方式获取消息,消息有序,通过控制能够保证所有消息被消费且仅被消费一次;有优秀的第三方Kafka Web管理界面Kafka-Manager;在日志领域比较成熟,被多家公司和多个开源项目使用;主要支持简单的MQ功能,在大数据领域的实时计算以及日志采集场景中大规模使用。 缺点:单机超过64个队列/分区,Load会发生明显的飙高现象,队列越多,Load越高,发送消息响应时间变长,使用短轮询方式,实时性取决于轮询间隔时间,消费失败不支持重试;支持消息顺序,但是一台代理宕机后,就会产生消息乱序,社区更新较慢。 ②ActiveMQ ActiveMQ是一款非常古老的MQ。 优点:单机吞吐量万级,时效性ms级,可用性高,基于主从架构实现高可用性,消息可靠,丢失数据的概率较低。 缺点:官方社区现在对ActiveMQ 5.x维护越来越少, 高吞吐量场景较少使用。 ③RocketMQ RocketMQ是阿里巴巴开源产品,用Java语言实现,在设计时参考了Kafka,并做出些改进,被阿里巴巴广泛应用。 优点:单机吞吐量十万级,可用性非常高,分布式架构,消息可以做到0丢失,MQ功能较为完善,扩展性好,支持10亿级别的消息堆积,不会因为堆积导致性能下降。 缺点:支持的客户端语言不多,目前是java及C++,其中C++不成熟;社区活跃度一般,没有在MQ核心中实现JMS等接口,有些系统要迁移需要修改大量代码。 ④RabbitMQ 2007年发布,是一个在AMQP(高级消息队列协议)基础上完成的,可复用的企业消息系统,是当前最主流的消息中间件之一。 优点:由于erlang语言的高并发特性,性能较好;吞吐量到万级,MQ功能比较完备、健壮、稳定、易用、跨平台、支持多种语言,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX文档齐全;开源提供的管理界面非常棒,用起来很好用,社区活跃度高,更新频率相当高。 缺点:商业版需要收费,学习成本较高
RabbitMQ工作原理
RabbitMQ核心概念
RabbitMQ的高级应用①死信队列 死信队列(DLX,Dead-Letter-Exchange),利用DLX,当消息在一个队列中变成无法被消费的消息(dead message)之后,它能被重新publish到另一个Exchange,这个Exchange就是DLX。 消息变成死信的几种情况: 1、 消息被拒绝( 2、 消息在队列的存活时间超过设置的生存时间(TTL)时间; 3、 队列达到最大长度(队列满了,无法再添加数据到队列中)。 DLX也是一个正常的Exchange,和一般的Exchange没有区别,它能在任何的队列上被指定,实际上就是设置某个队列的属性。 死信队列的设置: 1、首先,需要设置死信队列的Exchange和queue,然后进行绑定; 2、然后,我们进行正常声明交换机、队列、绑定,只不过我们需要在队列机上一个参数即可:arguments.put(“x-dead-letter-exchange”,”dlx.exchange”);这样消息在过期、被拒绝、队列在达到最大长度时,消息就可以直接路由到死信队列。 ②延迟队列 基于 应用场景:
③队列幂等性 幂等性的实质是:对于一个资源,不管你请求一次还是请求多次,对该资源本身造成的影响应该是相同的,不能因为重复相同的请求而对该资源重复造成影响。注意关注的是请求操作对资源本身造成的影响,而不是请求资源返回的结果。 MQ消费者的幂等性一般使用全局ID或者写个唯一标识(比如流水号/时间戳/UUID/订单号)来判断该消息是否已消费过,也可以利用redis执行setnx命令,天然具有幂等性,从而实现不重复消费(推荐使用redis)。 ④优先级队列 优先级队列,也就是具有高优先级的队列,优先级高的消息具备优先被消费的特权。通过队列的 x-max-priority 参数设置队列的最大优先级,之后在发送消息时通过 priority 属性再设置当前消息的优先级。优先级应在 0 和 255 之间,推荐1 ~ 10。
⑤惰性队列 惰性队列会尽可能地将消息存入磁盘中,而在消费者消费消息时才会被加载到内存中,它支持更多的消息存储。 队列具备两种模式:default 和 lazy。默认的为 default 模式,在队列声明的时候可以通过“x-queue-mode”参数来设置队列的模式,取值为“default”和“lazy”。 |
|