一、Rocke的安装
RocketMQ 是阿里巴巴开源的分布式消息中间件。支持事务消息、顺序消息、批量消息、定时消息、消息回溯等。它里面有几个区别于标准消息中件间的概念,如Group、Topic、Queue等。系统组成则由Producer、Consumer、Broker、NameServer等。
环境变量配置
ROCKETMQ_HOME="D:\rocketmq"
NAMESRV_ADDR="localhost:9876"
下图:
这里建议配置两个环境变量都配置,第一个是RocketMQ的安装路径,第二个是NameServer的地址。
理论
- Producer:消息发布的角色,支持分布式集群方式部署。Producer通过MQ的负载均衡模块选择相应的Broker集群队列进行消息投递,投递的过程支持快速失败并且低延迟。
- Consumer:消息消费的角色,支持分布式集群方式部署。支持以push推,pull拉两种模式对消息进行消费。同时也支持集群方式和广播方式的消费,它提供实时消息订阅机制,可以满足大多数用户的需求。
- NameServer:NameServer是一个非常简单的Topic路由注册中心,支持Broker的动态注册与发现。主要包括两个功能:
1. Broker管理,NameServer接受Broker集群的注册信息并且保存下来作为路由信息的基本数据。
2. 提供心跳检测机制,检查Broker是否还存活;
3. 路由信息管理,每个NameServer将保存关于Broker集群的整个路由信息和用于客户端查询的队列信息。然后Producer和Conumser通过NameServer就可以知道整个Broker集群的路由信息,从而进行消息的投递和消费。NameServer通常也是集群的方式部署,各实例间相互不进行信息通讯。Broker是向每一台NameServer注册自己的路由信息,所以每一个NameServer实例上面都保存一份完整的路由信息。当某个NameServer因某种原因下线了,Broker仍然可以向其它NameServer同步其路由信息,Producer,Consumer仍然可以动态感知Broker的路由的信息。- BrokerServer:Broker主要负责消息的存储、投递和查询以及服务高可用保证,为了实现这些功能,Broker包含了以下几个重要子模块。
a. Remoting Module:整个Broker的实体,负责处理来自clients端的请求。
b. Client Manager:负责管理客户端(Producer/Consumer)和维护Consumer的Topic订阅信息
c. Store Service:提供方便简单的API接口处理消息存储到物理硬盘和查询功能。
d. HA Service:高可用服务,提供Master Broker 和 Slave Broker之间的数据同步功能。
e. Index Service:根据特定的Message key对投递到Broker的消息进行索引服务,以提供消息的快速查询。
RocketMQ 特点
- 是一个队列模型的消息中间件,具有高性能、高可靠、高实时、分布式等特点
- Producer、Consumer、队列都可以分布式
- Producer 向一些队列轮流发送消息,队列集合称为 Topic,Consumer 如果做广播消费,则一个 Consumer 实例消费这个 Topic 对应的所有队列,如果做集群消费,则多个 Consumer 实例平均消费这个 Topic 对应的队列集合
- 能够保证严格的消息顺序
- 支持拉(pull)和推(push)两种消息模式
- 高效的订阅者水平扩展能力
- 实时的消息订阅机制
- 亿级消息堆积能力
- 较少的依赖
基本使用
- 创建maven quickstart项目
- 添加依赖
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>4.9.1</version>
</dependency>
生产者
(1)创建生产者
// 根据分组名称将producer进行分组
DefaultMQProducer producer = new DefaultMQProducer("TestSender");
// 设置producer注册的NameServer的地址以及端口
producer.setNamesrvAddr(localhost:9876);
(2)启动producer
producer.start();
(3)构建消息并发送
这里的TOPIC是指定topic主题,user_register是tag标签,消息发送必须指定主题,标签以及发送的消息内容
这里的要发送则必须将内容转换成bytes字节才能进行消息发送
Message msg = new Message("TOPIC", "user_register",Content.getBytes("UTF-8"));
(4)消息发送
SendResult sendResult = producer.send(msg);
消费者
(1)创建消费者实例
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("TestReceive"); consumer.setNamesrvAddr(localhost:9876);
(2)订阅某个主题,以及指定主题下面的标签名 *代表该主题下的所有标签都订阅
consumer.subscribe(TOPIC,"*");
(3)向MQ注册一个监听器 监听器监听生产者向消费者发送的消息(这段代码我还没有搞清楚)
consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
for (MessageExt msgExt:msgs){
try {
System.out.println("消息内容:"+new String(msgExt.getBody(),"utf-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
});
(4)启动消费者实例
consumer.start();
发送的三种模式
发送-同步确认发送结果
同步发送是指消息发送方发出一条消息后,会在收到服务端同步响应之后才发下一条消息的通讯方式。
● 应用场景:此种方式应用场景非常广泛,例如重要通知邮件、报名短信通知、营销短信系统等。
发送-异步确认发送结果
异步发送是指发送方发出一条消息后,不等服务端返回响应,接着发送下一条消息的通讯方式。消息队列RocketMQ版的异步发送,需要您实现异步发送回调接口(SendCallback)。消息发送方在发送了一条消息后,不需要等待服务端响应即可发送第二条消息。发送方通过回调接口接收服务端响应,并处理响应结果。
● 应用场景:异步发送一般用于链路耗时较长,对响应时间较为敏感的业务场景,例如,您视频上传后通知启动转码服务,转码完成后通知推送转码结果等。
发送-结束 (单向发送) oneway
发送方只负责发送消息,不等待服务端返回响应且没有回调函数触发,即只发送请求不等待应答。此方式发送消息的过程耗时非常短,一般在微秒级别。
● 应用场景:适用于某些耗时非常短,但对可靠性要求并不高的场景,例如日志收集。
consumer 消息过滤
通过tag进行标签的过滤
通过订阅同一topic主题下的不同tag标签,来实现消息的收发不同
consumer.subscribe(AppConstants.SMS_TOPIC,"*");
consumer.subscribe(AppConstants.SMS_TOPIC,"user_reg");
consumer.subscribe(AppConstants.SMS_TOPIC,"user_reg || user_cancel");
栗子:
发送短信为栗子
不同的发送程序对应不同的内容,接受消息的consumer也会不同,所以通过tag标签进行区域划分
消费模式
分为两种:
1.一种集群模式----->>>>>>>>>>>>同一个sender发出去,只对应一个recevier可以接收到
2.一种群发模式----->>>>>>>>>>>>同一个sender发出去,但凡订阅了该主题(包含tag)的recevier都可以接收到相同的消息