@
RocketMQ (1)
MQ message queue
简单来说,消息队列就是基础数据结构课程里“先进先出”的一种数据结构,但是如果要消除单点故障,保证消息传输的可靠性,并且还能应对大流量的冲击,对消息队列的要求就很高了。分布式消息队列可以提供应用解耦
、流量消峰
、消息分发
等功能,已经成为大型互联网服务架构里标配的中间件。
应用解耦
以电商为例,下单之后,需要使用库存,物流,支付等系统。如果任何一个子系统故障或其他原因导致不可用,都会使下单失败,影响用户,但是如果将要处理的信息使用MQ来传递,即使子系统不可用,也可以在短时间内恢复后,重新处理之前的信息,保证下单流程无问题。
流量消峰
如果订单系统每秒钟可以处理1W次下单,而且可以在规定的时间内返回结果,普通的场景下是没问题的。但是如果遇到流量高峰,比如促销,抢购等场景,十万百万的下单请求到达系统,结果就是系统直接挂了,正常的请求也无法继续执行。
此时可以通过MQ来做缓冲,将所有下单请求放入MQ,按照请求入队的先后顺序进行处理,这样处理可能会慢,但是对于系统来说不会挂掉,甚至可以通过临时增加服务节点,将负载的压力平均分担下来。
消息分发
数据通过producer生产,进入队列,consumer可以通过对MQ的topic进行订阅,来获取消息,还可以通过tag,来指定MQ消费的种类。而且不同的consumer消费MQ,彼此是不会有影响的
基本结构
RocketMQ 由四部分组成: Producer
、Consumer
、 Broker
和 NameServer
Producer
:消息发布的角色,支持分布式集群方式部署。Producer通过MQ的负载均衡模块选择相应的Broker集群队列进行消息投递,投递的过程支持快速失败并且低延迟。
Consumer
消息消费的角色,支持分布式集群方式部署。支持以push推
,pull拉
两种模式对消息进行消费。同时也支持集群方式和广播方式的消费,它提供实时消息订阅机制,可以满足大多数用户的需求。
NameServer
NameServer是一个非常简单的Topic路由注册中心,其角色类似Dubbo中的zookeeper,支持Broker的动态注册与发现。主要包括两个功能:
Broker管理
,NameServer接受Broker集群的注册信息并且保存下来作为路由信息的基本数据。然后提供心跳检测机制,检查Broker是否还存活;
路由信息管理
,每个NameServer将保存关于Broker集群的整个路由信息和用于客户端查询的队列信息。然后Producer和Conumser通过NameServer就可以知道整个Broker集群的路由信息,从而进行消息的投递和消费。NameServer通常也是集群的方式部署,各实例间相互不进行信息通讯。Broker是向每一台NameServer注册自己的路由信息,所以每一个NameServer实例上面都保存一份完整的路由信息。当某个NameServer因某种原因下线了,Broker仍然可以向其它NameServer同步其路由信息,Producer,Consumer仍然可以动态感知Broker的路由的信息。 NameServer是最高的管理层。
BrokerServer
主要负责消息的存储、投递和查询以及服务高可用保证。可以看成是快递小哥。
producer 和 consumer是MQ中的2个重要角色。
consumer对于消息处理有2种模式pull,push,所以对应了2种
-
DefaultMQPushConsumer
由系统控制读取操作,收到消息后自动调用传入的处理方法来处理
-
DefaultMQPullConsumer
读取操作中的大部分功能由使用者自主控制。
Producer默认使用的是DefaultMQProducer
在设置好group,topic,nameserver,就可以准备发送消息了,发送的消息一般会立即进入队列等待consumer获取,但是也可以通过设置延迟消费的时间,来控制消息在发送后一段时间后被消费
Rocket 消息模式
Clustering集群
同一个ConsumerGroup里所有的Consumer消费的内容合起来才是所订阅的topic的全部消息
Broadcasting广播
同一个ConsumerGroup里的每个Consumer都能消费到所订阅topic的全部消息,也就是说消息会被每个Consumer都消费一次。
MQ消费的问题
看到这里,基本对MQ都有一定熟悉了,如果还使用过的话,会发现MQ在使用过程中会存在一些问题的。
比如消费重复,发送时的重复,投递时重复,负载均衡的重复;消息的堆积等。
下次有空在整理