项目场景:

在使用seata的过程中碰到一个BUG,在mysql集群连接的情况下,使用seata的AT模式出现问题。


问题描述

简单描述一下我的使用场景和问题:

Spring Cloud Alibaba 2.2.6.RELEASE + Spring Boot 2.3.2.RELEASE + seata 1.5.2 + mysql8.0 + nacos

有若干个服务,服务A、服务B、服务C,并配置了seata 1.5.2,且正常使用,使用AT模式。

在使用MySql集群时候出现问题,问题出现在服务A、服务B、服务C使用mysql集群连接串时候,全局事务出现如下错误:

10:52:40.627 ERROR --- [Pool.commonPool-worker-11] io.seata.server.coordinator.DefaultCore  : Committing branch transaction exception: BR:4323970364623622157/4323970364623622146
No channel is available for resource[jdbc:mysql://192.168.10.41:19131,192.168.10.42:19131/assets]
==>
java.lang.RuntimeException: rm client is not connected. dbkey:jdbc:mysql://192.168.10.41:19131,192.168.10.42:19131/assets,clientId:assets:192.168.10.41:55934
	at io.seata.core.rpc.netty.AbstractNettyRemotingServer.sendSyncRequest(AbstractNettyRemotingServer.java:69)
	at io.seata.server.coordinator.AbstractCore.branchCommitSend(AbstractCore.java:175)
	at io.seata.server.coordinator.AbstractCore.branchCommit(AbstractCore.java:165)
	at io.seata.server.coordinator.DefaultCore.lambda$doGlobalCommit$1(DefaultCore.java:204)
	at io.seata.server.session.SessionHelper.forEach(SessionHelper.java:244)
	at io.seata.server.coordinator.DefaultCore.doGlobalCommit(DefaultCore.java:192)
	at io.seata.server.coordinator.DefaultCoordinator.lambda$handleAsyncCommitting$4(DefaultCoordinator.java:441)
	at io.seata.server.session.SessionHelper.lambda$forEach$0(SessionHelper.java:223)
	at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1384)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
	at java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291)
	at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1067)
	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1703)
	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:172)
<==

原因分析:

看错误是在操作分支事务提交的时候,获取不到Channel,无法建立连接,但是不知道应该怎么解决。

我在官网和各个论坛以及博客都没有找到相关错误,于是请教了seata的开发者,给seata的开发者发送了一封邮件,然后在github提了一个Issues反应这个bug。

在这里插入图片描述


解决方案:

在seata开发者的帮助下解决了这个问题:
在这里插入图片描述
在mysql集群连接,一定要配置负载均衡参数(loadbalance)才能被识别生效。

最终在各个服务的mysql连接效果如下:
jdbc:mysql:loadbalance://192.168.10.41:19131,192.168.10.42:19131/assets?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true

感谢seata开发者的帮助,抱拳!!!

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐