mycat自动重启解决办法
mycat自动重启解决办法
前言
mycat是一个非常著名的分库分表中间件,但是很多使用过这个中间件的人都会遇到一个共通的问题,那就是mycat的进程总是会重启,同时重启的时候应用的代码里面也会报出 Java.lang.NullPoint_er_Exception , 今天就来分析一下这个问题,以及解决办法!
原理
这个mycat的重启问题可能一部分人遇到了,一部分人没有遇到过,这是为什么呢?
实际上这段mycat的bug代码是出现在了跨库结果集合并后,释放堆外内存的代码上面
有一部分有经验的人知道分库分表中间件是不太适用于跨库查询的,这些有经验的人会让业务代码去一个一个库查出数据库后,让业务代码自己去做数据合并,排序的逻辑,如果是这样的话就完美避开了这个问题。
比如我用mycat的注解
/#mycat: datanode=dn1/select * from ljj_table
/#mycat: datanode=dn2/select * from ljj_table
这样就强行指定了datanode的节点,就算我sql里面没有分库字段也可以去这个库里面查出数据。然后在业务里面把select出来的结果进行合并
但是对于很多中小型的公司来说,因为经验不足,以及代码的快速迭代,是允许mycat跨库查询的,这就导致了mycat内部需要做排序,这样做的话就有几率触发堆外内存重复释放的bug导致重启。
比如我直接执行
select * from ljj_table
这样的sql,mycat内部就会进行汇聚以及排序,就会导致空指针。
代码REVIEW以及修改方法
这个问题的代码主要问题就是出在了 MultiNodeQueryHandler
这个类上面,在这个类里面,有几个释放资源的类需要做出修改。
在方法 outputMergeResult(这个类里面有2个outputMergeResult,都要改!)
里面,我们需要调整释解锁与释放堆外内存的顺寻
原先是
lock.unlock();
dataMergeSvr.clear();
现在我们需要改成
dataMergeSvr.clear();
lock.unlock();
以及在这个类的clearResources方法里面,我们需要加上锁
原先是
if(dataMergeSvr!=null){
dataMergeSvr.clear();
}
现在改成
lock.lock();
try{
if(dataMergeSvr!=null){
dataMergeSvr.clear();
}
}finally{
lock.unlock();
}
这样改完后,我们就保证了dataMergeSvr.clear()这个方法的原子性。
还有在AbstractConnection这个类上面的cleanup方法上面加上sync的锁,这样mycat的重启问题就彻底修复了。
如果不修改源码重新打包?有什么简单的方法可以直接改掉这个类吗?(针对dba和运维)
答案是可以的!我知道很多公司维护mycat的都是dba和运维,这里可以利用mycat自带的wrapper功能(加载外部jar包)来进行直接修复
我把我改完的这2个类的jar(仅针对mycat1.6版本)已经上传到了网盘
链接:https://pan.baidu.com/s/1coay5H-QE7ED26UWuKsL5g
提取码:ygad
把我的这个jar包mycatExtend.jar放到mycat的lib目录下
比如Mycat-server-1.6mycatlib下面
然后在conf文件里面的wrapper.conf这个文件里面设置地址
# Java Classpath (include wrapper.jar) Add class path elements as
# needed starting from 1
wrapper.java.classpath.1=lib/mycatExtend.jar
wrapper.java.classpath.2=lib/wrapper.jar
wrapper.java.classpath.3=conf
wrapper.java.classpath.4=%REPO_DIR%
这样就大功告成啦~~~启动mycat!问题修复!!!!!
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
HBase2.0 replication wal znode大量积压问题定位解决
现象 线上有2个集群A和B,配置了双向同步,单活,即业务层某一时刻只会访问其中一个集群;近期A集群的regionserver日志中报了很多异常,但监控页面正常,功能也未受影响。 HBase版本为2.0.0; 2019-09-04 02:44:58,115 WARN org.apache.zookeeper.ClientCnxn: Session 0x36abf38cec5531d for server host-15/ip-15:2181, unexpected error, closing socket connection and attempting reconnect java.io.IOException: Broken pipe at sun.nio.ch.FileDispatcherImpl.write0(Native Method) at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47) at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93...
- 下一篇
java单元/集成测试中使用Testcontainers
java单元/集成测试中使用Testcontainers 1.Testcontainers介绍:#Testcontainers是一个Java库,它支持JUnit测试,提供公共数据库、SeleniumWeb浏览器或任何可以在Docker容器中运行的轻量级、一次性实例。 测试容器使以下类型的测试更加容易: 数据访问层集成测试: 使用MySQL,PostgreSQL或Oracle数据库的容器化实例测试您的数据访问层代码,但无需在开发人员的计算机上进行复杂的设置,并且测试将始终从已知的数据库状态开始,避免“垃圾”数据的干扰。也可以使用任何其他可以容器化的数据库类型。 应用程序集成测试: 用于在具有相关性(例如数据库,消息队列或Web服务器)的短期测试模式下运行应用程序。 UI /验收测试: 使用与Selenium兼容的容器化Web浏览器进行自动化UI测试。每个测试都可以获取浏览器的新实例,而无需担心浏览器状态,插件版本或浏览器自动升级。您将获得每个测试会话或测试失败的视频记录。 更多: 可以签出各种贡献的模块,或使用GenericContainer作为基础创建自己的自定义容器类。 2.Test...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2全家桶,快速入门学习开发网站教程
- Hadoop3单机部署,实现最简伪集群
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS关闭SELinux安全模块
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS8安装Docker,最新的服务器搭配容器使用