1. 业务场景
在使用Canal订阅binlog的过程中,我们观察到一个现象:尽管有大量的Topic,消息却默认发送到MQ的第一个队列。这导致当消费者服务启动并查询动态注册的消费者时,只有最先启动的消费者能够注册大量消费者,进而造成单点性能问题。
2. 解决方案探索
首先想到的是从消费者端进行负载均衡
思路1:
原来的消费者服务作为代理服务,负责转发消息到新的Topic,然后新增一个消费者服务,消费新的Topic
逻辑处理清晰易懂,但是需要新增一个服务
思路2:在原来的消费者服务基础上,进行负载均衡,按照表名进行Hash。不同的服务消费对应的Topic
目测可行,由于下面找到问题的根本原因,所以没试
3. 深入Canal源码
在我开始阅读Canal的源码时,我们发现在初始化canalMQProducer.init时,会构建一个线程池,这个线程池管理着对不同RocketMQ队列的消息发送任务。进一步的研究让我们找到了partitionsNum和partitionHash这两个关键的参数配置
下面贴出我们生产上当时的配置
canal