参考:https://www.javazhiyin.com/?post_type=post&s=rocket
目录
十一、举例说明消息队列应用场景及ActiveMQ、RocketMQ、Kafka等的对比
一、组件
(一)Broker
用于producer和consumer接收和发送消息。broker会定时向nameserver提交自己的信息,每个Broker节点,在启动时,都会遍历NameServer列表,与每个NameServer建立长连接,注册自己的信息,之后定时上报。是消息中间件的消息存储、转发服务器。
(二)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的路由的信息。
(三)Producer
消息的生产者。随机选择其中一个NameServer节点建立长连接,获得Topic路由信息(包括topic下的queue,这些queue分布在哪些broker上等等),接下来向提供topic服务的master建立长连接(因为rocketmq只有master才能写消息),且定时向master发送心跳。
(四)Consumer
消息的消费者。通过NameServer集群获得Topic的路由信息,连接到对应的Broker上消费消息。由于Master和Slave都可以读取消息,因此Consumer会与Master和Slave都建立连接进行消费消息。
(五)windows环境服务启动
参考:https://www.cnblogs.com/linjiqin/p/9553663.html
1、启动mq的namesrver服务;
2、启动mq的broker服务;
3、控制台安装,可以查看消息相关内容
(六)整个流程
1、启动NameServer,NameServer起来后监听端口,等待Broker、Producer、Consumer连上来,相当于一个路由控制中心。
2、Broker启动,跟所有的NameServer保持长连接,定时发送心跳包。心跳包中包含当前Broker信息(IP+端口等)以及存储所有Topic信息。注册成功后,NameServer集群中就有Topic跟Broker的映射关系。
3、收发消息前,先创建Topic,创建Topic时需要指定该Topic要存储在哪些Broker上,也可以在发送消息时自动创建Topic。
4、Producer发送消息,启动时先跟NameServer集群中的其中一台建立长连接,并从NameServer中获取当前发送的Topic存在哪些Broker上,轮询从队列列表中选择一个队列,然后与队列所在的Broker建立长连接从而向Broker发消息。
5、Consumer跟Producer类似,跟其中一台NameServer建立长连接,获取当前订阅Topic存在哪些Broker上,然后直接跟Broker建立连接通道,开始消费消息。
二、核心概念
1、Message
消息载体。Message发送或者消费的时候必须指定Topic。Message有一个可选的Tag项用于过滤消息,还可以添加额外的键值对。
2、topic
消息的逻辑分类,发消息之前必须要指定一个topic才能发,就是将这条消息发送到这个topic上。消费消息的时候指定这个topic进行消费。就是逻辑分类。
3、queue
1个Topic会被分为N个Queue,数量是可配置的。message本身其实是存储到queue上的,消费者消费的也是queue上的消息。多说一嘴,比如1个topic4个queue,有5个Consumer都在消费这个topic,那么会有一个consumer浪费掉了,因为负载均衡策略,每个consumer消费1个queue,5>4,溢出1个,这个会不工作。
4、Tag
Tag 是 Topic 的进一步细分,顾名思义,标签。每个发送的时候消息都能打tag,消费的时候可以根据tag进行过滤,选择性消费。RocketMQ的消费者可以根据Tag进行消息过滤,也支持自定义属性过滤。消息过滤目前是在Broker端实现的,优点是减少了对于Consumer无用消息的网络传输,缺点是增加了Broker的负担、而且实现相对复杂。
5、Message Model
消息模型:集群(Clustering)和广播(Broadcasting)
6、Message Order
消息顺序:顺序(Orderly)和并发(Concurrently)
7、Producer Group
消息生产者组。
group含义:代表具有相同角色的生产者组合或消费者组合,称为生产者组或消费者组。
如果不指定,就会使用默认的名字:DEFAULT_PRODUCER。作用是在集群HA的情况下,一个生产者down之后,本地事务回滚后,可以继续联系该组下的另外一个生产者实例,不至于导致业务走不下去。在消费者组中,可以实现消息消费的负载均衡和消息容错目标。
8、Consumer Group
消息消费者组。
消费组可以消费不同生产组生产的同一topic的消息。
9、ACK
ACK机制是发生在Consumer端的,不是在Producer端的。也就是说Consumer消费完消息后要进行ACK确认,如果未确认则代表是消费失败,这时候Broker会进行重试策略(仅集群模式会重试)。ACK的意思就是:Consumer说:ok,我消费成功了。这条消息给我标记成已消费吧。
三、消费模式
(一)消费模式
1、集群模式(Clustering)
每条消息只需要被处理一次,broker只会把消息发送给 消费集群中 的一个消费者(不是满足条件的topic的一个消费者,是某个消费集群中的一个消费者);
在消息重投时,不能保证路由到同一台机器上;
消费状态由broker维护;
默认就是集群模式;
2、广播模式(Broadcasting)
消费进度由consumer维护。
保证每个消费者都消费一次消息。
消费失败的消息不会重投。
consumer.setMessageModel(MessageModel.BROADCASTING);
(二)消费方式
1、拉取式消费
Consumer消费的一种类型,应用通常主动调用Consumer的拉消息方法从Broker服务器拉消息、主动权由应用控制。一旦获取了批量消息,应用就会启动消费过程。
2、推动式消费
Consumer消费的一种类型,该模式下Broker收到数据后会主动推送给消费端,该消费模式一般实时性较高。
(三)消息发送模式
1、send(同步)
//同步获取到结果
SendResult result = producer.send(msg);
2、send(批量)
// 批量发送的api的也是send(),只是他的重载方法支持List<Message>,同样是同步发送。
SendResult result = producer.send(msgs);
3、sendCallBack(异步)
producer.send(msg, new SendCallback() {
// 发送成功的回调接口
@Override
public void onSuccess(SendResult sendResult) {
System.out.println("发送消息成功!