一、背景
技术背景: mysql-connector-java 8.0.21、mycat 1.6.75 、tkmybatis、pagehelper
问题背景:项目启动后,请求A接口,A接口有相关日志打印,如下所示,就是没有数据返回。之后再请求,没有反应,进不去,也没报错。重启之后,才可以访问。
类似的其他接口请求,有数据返回,没有问题。
二、问题排查
1、由于是分页接口,注释 PageHelper.startPage(pageNum, pageSize); 接口可以返回数组数据。怀疑是分页插件影响,于是开启debug模式,debug过程如下:
业务方法:workPhotoUserVerifyMapper.getWorkPhotoMsgByPage(userIds, status)
进入:MapperProxy 的 invoke(Object proxy, Method method, Object[] args) 方法,接着 MapperMethod 的 execute(SqlSession sqlSession, Object[] args) 方法并进行select操作的方法:executeForMany(SqlSession sqlSession, Object[] args) 。接着 进入 SqlSessionTemplate 的 selectList(String statement, Object parameter) 方法,方法内接着进入 invoke(Object proxy, Method method, Object[] args)。其余过程省略,我们看看这个调用栈:
最后分页的时候执行:this.socketConnection.getMysqlInput().readFully(hdr.getBuffer().array(), 0, NativeConstants.HEADER_LENGTH); 出现阻塞。此时排除分页插件 PageHelper的影响。从以上的调用栈,猜测是驱动出现了问题。
2、找DBA沟通,看看我这边的SQL是否执行到mycat,mycat有木有响应结果。经过沟通,mycat的sql如下:
SELECT
v.id AS verifyId,
v.user_id AS userId,
v.origin,
v.create_time AS commitTime,
v.audited_status AS auditedStatus,
v.image,
v.audited_time AS auditedTime
FROM
work_photo_user_verify v
WHERE
v.user_id IN ( 1, 2, 3, 4 )
ORDER BY
v.create_time DESC; LIMIT 0,10
mycat返回的错误信息:ERROR [$_NIOREACTOR-0-RW] (io.mycat.backend.mysql.nio.MySQLConnectionHandler.handleErrorPacket(MySQLConnectionHandler.java:193)) - receive ErrorPacket but no handler
原因分析:mysql 驱动一直等待mycat响应,mycat抛出异常,但驱动没有捕获到,以为一直没有响应,就这样卡在这里。
LIMIT 0,10 是分页插件帮我组装的分页SQL,我的分页语句如下:
改正:去掉 DESC;的; 解决阻塞问题,接口正常有数据返回。
三、总结
1、还是自己粗心引起的,同时没有理解分页插件PageHelper的执行过程。
2、猜想:mycat抛出异常,MySQL驱动没有捕获到,估计是两者的版本存在差异。或者MySQL驱动对接的是MySQL,没考虑兼容mycat,而mycat是基于MySQL协议开发的数据库中间件,也就是mycat没有兼容好MySQL最新协议(纯属瞎想,如有伙伴知道原因,麻烦告知一下,谢谢)