一基础配置
我们先展示生产者发送消息的示例代码。
// 1. 初始化默认生产者,传递参数生产者组名
DefaultMQProducer producer = new DefaultMQProducer(PRODUCER_GROUP);
// 2. 设置名字服务地址
producer.setNamesrvAddr(“name-server1-ip:9876;name-server2-ip:9876”);
// 3. 启动生产者服务
producer.start();
// 4. 定义消息对象
Message msg = new Message(TOPIC /* Topic /,
*TAG /* Tag /,
(“Hello RocketMQ “ + i).getBytes(RemotingHelper.DEFAULT_CHARSET) / Message body */
);
msg.setKeys(“”);
// 5. 发送消息
// 示例普通消息
SendResult sendResult = producer.send(msg);
// 示例异步回调
producer.send(msg, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
// do something
}
@Override
public void onException(Throwable e) {
// do something
}
});
// 示例 oneway 发送
producer.sendOneway(msg);
发送流程如下:
1、初始化默认生产者,传递参数生产者组名;
2、设置名字服务地址 ;
3、启动生产者服务;
4、定义消息对象 ;
5、生产者支持普通发送、oneway 发送、异步回调三种方式发送消息 。
二、发送消息流程
1、构造函数
下图展示了生产者 DefaultMQProducer 类的构造函数,包装类 DefaultMQProducerImpl 是我们这一小节的核心。
构造函数包含两个部分:
1.1、初始化实现类 DefaultMQProducerImpl ;
1.2、根据是否开启消息轨迹参数 enableMsgTrace 判断是否增加消息轨迹逻辑 。
2、 启动生产者
DefaultMQProducer 类的 start 方法,本质上是调用包装类 DefaultMQProducerImpl 的 start 方法。
进入 DefaultMQProducerImpl 类,查看该类的逻辑 。
2.1、 检测配置
判断生产者组是否合法,生产者名称不能和默认生产者组名称相同。
2.2、创建客户端实例
MQClientInstance 对象通过 MQClientManager 这个单例类创建 ,标志着一个客户端实例,是非常核心的类,每一个实例对象有一个唯一的 clientId。
- 生产者表 / 消费者表引用
- 路由信息
2.3、 注册本地生产者
boolean registerOK = mQClientFactory.registerProducer(this.defaultMQProducer.getProducerGroup(), this);
注册本地生产者的本质是修改客户端实例的生产者表引用:
MQProducerInner prev = this.producerTable.putIfAbsent(group, producer);
2.4、启动客户端实例
实例启动后,会启动通讯模块、定时任务、负载均衡服务、消费者拉取服务。
下图展示了生产者发送消息时,IDEA 里的线程 DUMP 图:
我们需要重点讲讲定时任务 startScheduledTask 方法,定时任务如下图:
我们重点关注发送心跳和更新路由两个任务。
发送心跳: 定时任务每隔 30 秒将客户端信息发送到 Broker 。
当 Broker 收到心跳请求之后,会通过生产者管理器 ProducerManager、消费者管理器 ConsumerManager 分别更新生产者客户端缓存、消费者客户端缓存。
更新路由
对于生产者来讲,它需要知道需要发送消息的主题对应的路由信息,因此需要定时更新路由信息。