序言
这一段是我遇上问题的过程,可以直接跳转到下面的正文
在刚写的博客《Zdal分库分表介绍、超详细一步一步搭建简单的zdal框架》
【架构设计|找错(ZdalRuleCalculateException: 规则引擎计算出错,拆分值=)】中,是通过向线程中存放数据库远程路由来指定操作哪个数据库,在mybatis执
行插引用块内容入操作时,会从数据库中取出该数据库远程路由,执行插入。代码
如下:
//得到 数据库选择器标识路由条件---确定是存在哪一个数据库中
DBSelectorIDRouteCondition dbSelectorIDRouteCondition = new DBSelectorIDRouteCondition("t_blog", dbSelectorID, physicTableName);
//将分库分表添加到线程中
ThreadLocalMap.put(ThreadLocalString.ROUTE_CONDITION, dbSelectorIDRouteCondition);
其实zdal在执行插入、更新、删除这种有确定的索引(对应zdal-dev-rule.xml中处理异常正文
配置的映射规则的索引),是 不需要在执行数据库操作前指定操作的数据库,可
以直接进行插入、更新、删除。下面是我在直接删除时出现的报错,以及解决的
过程。
记一次找BUG的过程。希望能对有类似bug的你有所帮助。
1、异常错误内容
### Cause: com.alipay.zdal.rule.ruleengine.exception.ZdalRuleCalculateException: 规则引擎计算出错,拆分值={id=8}
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:200)
at org.apache.ibatis.session.defaults.DefaultSqlSession.delete(DefaultSqlSession.java:213)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:434)
... 30 more
Caused by: com.alipay.zdal.rule.ruleengine.exception.ZdalRuleCalculateException: 规则引擎计算出错,拆分值={id=8}
at com.alipay.zdal.rule.groovy.GroovyListRuleEngine.evalueateSamplingField(GroovyListRuleEngine.java:139)
at com.alipay.zdal.rule.ruleengine.rule.CartesianProductBasedListResultRule.evalOnceAndAddToReturnMap(CartesianProductBasedListResultRule.java:321)
at com.alipay.zdal.rule.ruleengine.rule.CartesianProductBasedListResultRule.evalElement(CartesianProductBasedListResultRule.java:254)
at com.alipay.zdal.rule.ruleengine.rule.CartesianProductBasedListResultRule.eval(CartesianProductBasedListResultRule.java:49)
at com.alipay.zdal.rule.bean.LogicTable.calculate(LogicTable.java:255)
at com.alipay.zdal.client.controller.SpringBasedRuleMatcherImpl.match(SpringBasedRuleMatcherImpl.java:71)
at com.alipay.zdal.client.controller.SpringBasedDispatcherImpl.getDBAndTables(SpringBasedDispatcherImpl.java:87)
at com.alipay.zdal.client.jdbc.ZdalStatement.getExecutionMetaData(ZdalStatement.java:720)
at com.alipay.zdal.client.jdbc.ZdalStatement.getExecutionContext1(ZdalStatement.java:562)
at com.alipay.zdal.client.jdbc.ZdalStatement.getExecutionContext(ZdalStatement.java:417)
at com.alipay.zdal.client.jdbc.ZdalPreparedStatement.executeUpdate(ZdalPreparedStatement.java:481)
at com.alipay.zdal.client.jdbc.ZdalPreparedStatement.execute(ZdalPreparedStatement.java:226)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:59)
at com.sun.proxy.$Proxy24.execute(Unknown Source)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:46)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:74)
at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:50)
at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:198)
... 36 more
Caused by: java.lang.IllegalArgumentException: 调用方法失败: public java.lang.Object RULE.eval(java.util.Map)
at com.alipay.zdal.rule.groovy.GroovyListRuleEngine.invoke(GroovyListRuleEngine.java:176)
at com.alipay.zdal.rule.groovy.GroovyListRuleEngine.imvokeMethod(GroovyListRuleEngine.java:150)
at com.alipay.zdal.rule.groovy.GroovyListRuleEngine.evalueateSamplingField(GroovyListRuleEngine.java:132)
... 59 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.alipay.zdal.rule.groovy.GroovyListRuleEngine.invoke(GroovyListRuleEngine.java:172)
... 61 more
Caused by: groovy.lang.MissingPropertyException: No such property: com for class: RULE
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:49)
at org.codehaus.groovy.runtime.callsite.GetEffectivePogoPropertySite.getProperty(GetEffectivePogoPropertySite.java:71)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:241)
at RULE.eval(script1501492281398.groovy:1)
... 66 more
2、解决过程
报错是ZdalRuleCalculateException:规则引擎计算出错,拆分值={id=8}
在检查了三遍相关配置文件,还有路由规则,还是没找到问题。实在没办法后,我通过设置断点,debug查看源码。定位到执行出错的地方在最后调用Method.invoke方法,如下图:
文章图片
发现method中参数不对,同我配置的映射规则不对,然后我开始定位是哪一步导致method中参数出的问题,发现method是在GroovyListRuleEngine类中初始化加载,随后我断点设置在初始化开始debug,如下图:
文章图片
问题查到这儿,发现这里的expression表达式对应的值不对,方法名对了,但是报名没有完全对上,个人的 zdal-dev.rule.xml配置文件为:
文章图片
3、解决问题
导致BUG出现的还是配置文件出错,大家别光看类名.方法名以及方法内容是否出错,再次检查一下前置包名是否有问题。
最后的结果很简单,寻找的过程比较曲折,绕了很多的弯,技巧就是耐心的看下去,会能看到zdal框架的一个运行整体流程。
推荐阅读
- 架构设计|使用Axon Framework探索CQRS架构系列(一)(命令, 命令总线 和 命令处理组件)
- 架构设计|购物车功能的优化完善
- 在服务器上排除问题的头5分钟
- Git 用户指南
- 服务器开发|实时游戏对战引擎MatchVS,我的对战旅程
- 架构设计|限流方案
- PHP|node中常用的几大模块
- 2021 VDC (vivo 互联网服务亿级用户的技术架构演进之路)
- 架构设计|一个极简、易用的灰度分流方案(内附源码)