RocketMq-发送消息

204 阅读2分钟

发送消息流程

Producer端-client模块

  1. 找到往哪台机器上发。根据消息中的Topic,获取到其路由信息(包括Broker地址)
  2. 找到往哪个消息队列发。负载均衡平均发到每个消息队列,且有容错机制,保证了高可用
  3. 创建消息。生成msgId
  4. 创建RemotingCommand-requestCommand
    • 生成opaqueId(自增1),每次创建会自增2,Broker接收到消息后会序列化导致再次+1
    • 生成code码,不同的code码代表不同的Neety请求处理器,以及不同的线程池,Producer#start会进行初始化

Producer端-remoting模块

  1. RemotingClient发送消息
  2. 创建ResponseFuture返回对象。以opaque为key,返回对象为value,放到responseTable中。
  3. 通过Netty的通道将请求发送到Broker端,等待处理结果。利用CountDownLatch阻塞等待response,当ResponseFuture中被设置了response,CountDownLatch就会解锁,就会获取到response

Broker端-remoting模块

  1. 分配任务。通道接收到后消息,丢给工作线程进行处理
  2. 保存消息
    • 通过code码获取到发送消息处理器与线程池
    • 异步执行保存逻辑,生成offsetId,保存到commitlog中,再保存到topic的对应队列中,生成queueId
  3. 创建RemotingCommand-responseCommand
  4. 通过Netty通道将响应发送到Producer端

Producer端-remoting模块

  1. 释放7步的等待锁。接收到处理结果,释放7步的等待锁
  2. 消息发送会进行重试。异步1次,同步3次,BrokerException、InterruptedException不会重试

发送消息时如何选择消息队列?

TopicPublishInfo.sendWhichQueue
每次自增ThreadLocal维护的变量,用该变量跟消息队列数量 取余。

发送消息的broker故障延迟机制?

因为NameServe不会主动告诉ProducerBroker宕机,而Client每30s才会更新Broker的信息,
在这期间内会重复向宕机的Broker发送消息。为了实现发送消息高可用就有了故障延迟机制 

Producer内存中维护了一个以BrokerName为key的Map,当消息发送失败后存储到Map中,
且有Broker的下次恢复时间,在这期间内会跳过故障的Broker

之前代运营使用eip,发消息总是提示超时是怎么回事