SPLWare/esProc

集算器 spl 出现卡死现象 疑似 使用 Boolean 类型做为锁导致其它线程都出于等待 !!!

jcjgithub opened this issue · 3 comments

集算器版本 :
社区版:20230228~ 到目前 github 最新的 都有此现象
连接方式 :jdbc 远程计算
这里的远程计算指的是

image

jvm 监控的截图:

image

根据监控的栈提示 找到对应的源代码位置:
com.scudata.server.unit.JdbcTask#executeJDBC

image

时间有限 我大致看了下代码 逻辑是 connection 不一样 ,对应的 JdbcTask 会不一样 看代码的逻辑 应该是想要保证 同一个 JdbcTask 对象 被并发调用的时候进行一个同步 。可是看我的监控截图就会发现 即使 connection 不一样还是 被阻塞了。
本质是因为 Boolean execFinished = false; 这个 java 底层是做了优化的 即用的同一个对象
用 javap 进行字节码查看 底层会调用

image

故就会出现卡死的现象 。推测你们的代码应该是想保证 同一个对象的同步 如果是这样的话 建议换成 其它数据类型来做锁对象 例如可以参考 spring 的 调整成:Object lockCondition= new Object(); 或者 Boolean execFinished = new Boolean(false);
看了 企业版的 20230901版本也有此问题。
我这里还有一个疑问点 ,看你们的代码片段 那段同步逻辑 应该是在等 上面的 new 出来的线程 返回的结果 。既然主线程都要去等这个结果 那我不 new Thread 直接调用 JDBCUtil.execute(cmd, args, context); 不就直接拿到了吗 这样也不用写 下面的同步逻辑 然后 也避免 new Thread 代码的 线程创建、销毁开销 及 cpu 的上下文切换 ,由于不太清楚你们的上下文逻辑 还麻烦解答下。
总结:本地计算是不会有这个问题的 因为没走这个逻辑。 按照实际生产环境来看 远程计算这种模式应该用的多 这样跟业务模块进行解耦。

感谢反馈!
关于死锁的问题刚刚修改提交了。(Modify PJDBC Task e8d801d
不直接execue而是使用线程的原因,是为了任务可以被中断取消,例如在jdbc中调用statement.cancel()

企业版也同步修复了,可以去论坛下载贴中更新esproc-bin.jar即可。
如果使用的源码,从github上更新就行。