Free HTML5 by FreeHTMl5.co 2017-07-31 17:55:00

记一次Zdal环境配置踩坑

-------------------------------------我是一条正文分割线-------------------------------------

序言

这一段是我遇上问题的过程,可以直接跳转到下面的正文

       在刚写的博客《Zdal分库分表介绍、超详细一步一步搭建简单的zdal框架》

中,是通过向线程中存放数据库远程路由来指定操作哪个数据库,在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框架的一个运行整体流程。