rocketmq 客户端源码

结论:

异步不会自动重传

事务使用同步

生产端要有序必须单线程同步(或多线程加内存屏障),异步时由于用户自行应用层定义重传导致包到达服务器会反一反

服务器肯定没有像tcp协议那样重排序,因为客户端msgid并不是严格+1

 

1 send 异步

org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl#send(org.apache.rocketmq.common.message.Message, org.apache.rocketmq.client.producer.SendCallback, long)

image

org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl#sendDefaultImpl

image

异步不会重试!!!

org.apache.rocketmq.remoting.netty.NettyRemotingAbstract#invokeAsyncImpl

信号量控流量

image

 netty发送

image

 

正常收到消息,

org.apache.rocketmq.remoting.netty.NettyRemotingServer.NettyServerHandler#channelRead0

org.apache.rocketmq.remoting.netty.NettyRemotingAbstract#processResponseCommand

image

如果超时,它不会拿到ResponseFuture导致重复处理

 

3秒一次检查timeout

image

org.apache.rocketmq.remoting.netty.NettyRemotingAbstract#scanResponseTable

image

直接异步回调https://blog.csdn.net/zhifou123456/article/details/138367681

 

 

 

2 事务

https://cloud.tencent.com/developer/article/1755892

image

image

提交数据库事务,然后同一个方法同步调用endTransaction

image

服务端回查,应该有一个事务id和handler的绑定

org.apache.rocketmq.remoting.netty.NettyRemotingClient.NettyClientHandler#channelRead0

org.apache.rocketmq.remoting.netty.NettyRemotingAbstract#processRequestCommand

org.apache.rocketmq.remoting.netty.NettyRemotingAbstract#buildProcessRequestHandler 

image

org.apache.rocketmq.client.impl.ClientRemotingProcessor#checkTransactionState

image

通过group来锁定哪个producer,原以为会用<txn_id, producer>

image

 

 

3 client生成msgid的代码

image

 

那么mq server端将有机会重排序,且该msg消费端幂等有序https://cloud.tencent.com/developer/article/1596533

想要实现顺序消费,发送方式必须为同步发送,异步发送无法保证消息的发送顺序!https://cloud.tencent.com/developer/article/1691273

个人认为这里的同步指 业务代码+mq 有确定的隔离的先后关系

异步无法确保是因为异步连重传都没有,需要靠应用层自己做,自然不能确保

msg到了操作系统后,就是tcp协议的事情了

 

 

 

4 接下去关键点在于,服务端有没有像tcp那样缓存等待缺包

image

image

相同的queue的msg并不遵循严格局部+1,意味着服务端无法意识到中间有包丢了

比如前后两个消息获得4,6的id,服务端拿到6时并不能说5没来,我再等一等

 

posted on 2025-08-29 21:34  silyvin  阅读(9)  评论(0)    收藏  举报