[总结]单个jvm内canal-client不能同时消费多个destination错误排查
2018-01-17 16:02
357 查看
单个jvm内canal-client不能同时消费多个destination错误排查
背景
背景,在dev环境,我们想模拟单个canal-client 消费mysql 单实例-多db库的bin-log的场景。于是canal-server端的配置文件,配置成了3个destination,conf文件夹下的目录明细如下: |- conf |—- item/instance.properties |—- settlement/instance.properties |—- trade/instance.properties |—-…… canal.properties文件中:canal.destinations=item,settlement,trade
canal-client 端使用如下代码进行订阅bin-log
package com.test.canal; import com.alibaba.otter.canal.client.CanalConnector; import com.alibaba.otter.canal.client.CanalConnectors; /** * 集群模式的测试例子 */ public class ClusterCanalClientDemo extends AbstractCanalClientTest { public ClusterCanalClientDemo(String destination){ super(destination); } public static void main(String args[]) { CanalConnector connectorItem = CanalConnectors.newClusterConnector("127.0.0.1:2181", "item", "", ""); final ClusterCanalClientDemo item = new ClusterCanalClientDemo("item"); item.setConnector(connectorItem); item.start(); CanalConnector connectorSettlement = CanalConnectors.newClusterConnector("127.0.0.1:2181", "settlement", "", ""); final ClusterCanalClientDemo settlement = new ClusterCanalClientDemo("settlement"); settlement.setConnector(connectorSettlement); settlement.start(); CanalConnector connectorTrade = CanalConnectors.newClusterConnector("127.0.0.1:2181", "trade", "", ""); final ClusterCanalClientDemo trade = new ClusterCanalClientDemo("trade"); trade.setConnector(connectorTrade); trade.start(); Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { try { logger.info("## stop the canal client"); item.stop(); } catch (Throwable e) { logger.warn("##something goes wrong when stopping canal:", e); } finally { logger.info("## canal client is down."); } } }); } }
按照预想,本来是server同时生产三个destination消息,然后client也同时消费三个destination中的消息。
but 由于对canal不是很熟悉,瞎子摸石头过河一样,每一步都是靠自我感觉去测试和验证。这其中肯定要遇到不少困难!
问题描述
当我运行上面的代码时,一个canal-client同时消费三个destination,订阅三个db库(item、settlement、trade)的bin-log,发现,总是只有两个destination能成功。而且成功的destination似乎是随机的,最重要的是没有任何地方有报错日志。这瞬间让人心情不好了。
问题排查
1.多次运行canal-client,发现简单的规律,item和settlement总是有一个消费正常,有一个消费失败。 2.于是认为,应该不是server端的问题。 3.接下来又把ClusterCanalClientDemo拆分成三个client同时运行,发现三个client都消费得好好的。 4.于是大胆得出一个结论,难道是canal-client 不支持同时消费大于2个以上destination?因为每次都只有2个destination能成功。 5.随后又觉得不科学,否则,一个destination就得单独起一个jvm来运行client,像dev,test这种环境,我岂不是要起很多个client来消费。 6.我再次仔细看了看server端配置。这回发现一些蛛丝马迹,item/instance.properties 和 settlement/instance.properties两个实例中的username和password是一样的。 7.最后,我抱着试一试的心态,重新为settlement创建一个新的账户,canal2/canal2,然后重新运行server,再重新运行client。 果然,三个destination都正常消费了。
结论
当canal-server配置多个instance时,使用的slaveId、username必须不一样,否则当同一个client消费多个destination的时候,会出现莫名其妙的问题。
备注
最后附上我的canal-server配置

item/instance.properties:
## mysql serverId canal.instance.mysql.slaveId = 1251 ###################### item 库 start ########################### # position info canal.instance.master.address = 127.0.0.1:3306 # username/password canal.instance.dbUsername = canal canal.instance.dbPassword = canal canal.instance.defaultDatabaseName = canal.instance.connectionCharset = UTF-8 # table regex canal.instance.filter.regex = db_item.canal_test1,db_item.tb_student1 # table black regex canal.instance.filter.black.regex = None
settlement/instance.properties:
## mysql serverId canal.instance.mysql.slaveId = 1252 ###################### item 库 start ########################### # position info canal.instance.master.address = 127.0.0.1:3306 # username/password canal.instance.dbUsername = canal2 canal.instance.dbPassword = canal2 canal.instance.defaultDatabaseName = canal.instance.connectionCharset = UTF-8 # table regex canal.instance.filter.regex = db_settlement.canal_test2,db_settlement.tb_student2 # table black regex canal.instance.filter.black.regex = None
trade/instance.properties:
## mysql serverId canal.instance.mysql.slaveId = 1253 ###################### item 库 start ########################### # position info canal.instance.master.address = 127.0.0.1:3306 # username/password canal.instance.dbUsername = canal3 canal.instance.dbPassword = canal3 canal.instance.defaultDatabaseName = canal.instance.connectionCharset = UTF-8 # table regex canal.instance.filter.regex = db_trade.canal_test3,db_trade.tb_student3 # table black regex canal.instance.filter.black.regex = None
相关文章推荐
- .net Kafka.Client多个Consumer Group对Topic消费不能完全覆盖研究总结(一)
- .net Kafka.Client多个Consumer Group对Topic消费不能完全覆盖研究总结(二)
- .net Kafka.Client多个Consumer Group对Topic消费不能完全覆盖研究总结(一)
- .net Kafka.Client多个Consumer Group对Topic消费不能完全覆盖研究总结(二)
- iis里不能同时启动多个站点的原因总结:
- 实现server程序,支持多个client同时连接,为每一个client分配一个进程
- [置顶] 用单个for循环同时循环多个变量解多元方程
- 错误 1 类型“System.Web.Mvc.ModelClientValidationRule”同时存在于“c:\Progra
- 同时安装vs2010和VS2012后IEnumerable<ModelClientValidationRule>编译错误
- 【C++初级】static用法总结、问题探讨及常见错误排查
- nodejs中使用async来对异步操作进行同步,避免多个异步同时启动引发连接错误
- 错误排查总结-cxf客户端调用报错(任何超类对此上下文都是未知的)
- WM_COPYDATA消息回顾和总结,以及如何解决WM_COPYDATA 发送CString消息的过程中,UNICODE字符不能被正确解析的错误
- shiro使用经验总结:【同时实现url和按钮的拦截,只能用配置文件。不需要用注解!!!已多次测试=@RequiresPermissions不能拦截url直接访问。只能拦截标签(鸡肋,不要用!!)
- JVM内存格局总结(技术如果不能换钱,那不过是垃圾而已)
- Windows下不能启动mysql服务--错误总结
- ###(很难找的页面错误)查询操作不需要 返回 操作成功后失败。【方法不能同时执行两个response返回两次数据。导致页面显示数据失败】
- 自定义View解决多个跑马灯不能同时执行的问题
- 错误排查总结-eclipse中junit test或者run main方法报错