-
Notifications
You must be signed in to change notification settings - Fork 7.6k
-
Notifications
You must be signed in to change notification settings - Fork 7.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
客户端高可用存在bug #171
Comments
如果可以明确重现,是否有修复的代码? |
canal版本是1.0.20 修复代码正在写,涉及到高可用的代码比较绕,还没写好,您可以看看有没有简便的修改方法。 |
还有就是SimpleCanalConnector类中的doConnect方法 channel.connect(address);//此处的address应该即时取一次,否则D2永远没机会拿到最新的canal-server的ip |
你的第4步,d2启动链接的canal是c1是因为时效性问题么?d2未能及时发现c2已经是主? 是的,没能发现,原因就在于这段代码 channel.connect(address);//此处的address应该即时取一次,否则D2永远没机会拿到最新的canal-server的ip |
看了下代码,如果第4步,d2启动链接时拿到的是c1,会在initRunning执行doConnect时执行失败,原本期望是通过客户端发起restart操作来处理,而d2因为是热备,可能是在异步initRunning回调时报错,无法触发client端的restart而导致长时间挂起 |
想了下一种比较简单的改法
|
是的,就是这么改的。 |
问题场景
1,canal有两台服务器c1和c2,c1处于激活状态
2,客户端使用ClusterCanalConnector进行消费,也是两台服务器d1和d2,d1处于激活状态
3,c1发生宕机,此时d1会执行【ClusterCanalConnector】的restart()方法。restart中有三步:
第一步,disconnect,会释放running节点;
第二步,线程休眠5秒钟;
第三步,尝试重连,重连的时候会执行initRunning()方法。
4,在d1释放running节点后,d2会被立即触发,执行initRunning()方法,initRunning中也有两大步:
第一步,抢占running节点
第二步,执行processActiveEnter()方法,该方法肯定会报错,因为此时d2连接的canal也是c1,执行initRunning的zk线程会异常退出,此时d2的mutex变量仍然为false,并且没有释放running节点
5,d1后续的重连都没意义了,因为d2没有释放running节点,所以d1的mutext变成了false
6,最终结果是d1和d2都阻塞了
7,此时关闭d2,d1的initRunning方法会被触发,但d1的processActiveEnter方法仍然会报错,d1仍然无法恢复消费
The text was updated successfully, but these errors were encountered: