|
|
51CTO旗下网站
|
|
移动端
创建专栏

源码面前,了无秘密

著名IT作家、译者侯捷老师以前在其著作中有句话,就是我们今天文章的标题「源码面前,了无秘密」。可以说相当精炼。高度概括了从源码中我们可以收获的内容。在源码中,无论是应用的调用逻辑,关系,各种设计都一目了然。

作者:侯树成|2018-09-02 16:17

著名IT作家、译者侯捷老师以前在其著作中有句话,就是我们今天文章的标题「源码面前,了无秘密」。可以说相当精炼。高度概括了从源码中我们可以收获的内容。在源码中,无论是应用的调用逻辑,关系,各种设计都一目了然。

为什么会突然想到这样一个题目呢?

是因为最近一个项目上线,其中有几个功能模块使用了 Redis 进行数据的缓存,包括权限信息也在其中。所以每个请求都会通过 Redis 进行鉴权。这块功能是我指导的一个小同学负责开发的。上线几天后出现了这样的问题:

问题现象是线上出现了大量的错误

  1. Cannot get Jedis connection; nested exception  
  2. is redis.clients.jedis.exceptions.JedisException:  
  3. Could not get a resource from the pool 

项目约等于小流量,上线时 Redis 的最大连接数开到了1000,用户数远小于最大连接数,Redis 使用的是公司的集群,稳定性也有保障,理论上是不该出现这种取不到资源的情况的。

小同学自行 Google了好久没找到问题具体原因。我提供的几个思路也没本质解决问题。不过好在调整配置可以在线下稳定复现。所以我在小同学的电脑上开始debug,跟源码。

和结对编程类似,我一边Debug,我一边给小同学讲 Redis 这个连接池的实现思路,目前怀疑的问题等等。小同学说自己刚才也在试着跟源码,但跟了两层之后,感觉调用越来越深,有点晕,就放弃了。

然后我继续Debug和讲原理,跟到资源使用完毕,在 finally 进行释放回收的地方,发现有处代码在判断当前的 dataSource是否为空,从而执行两种不同的操作。 如果不为空,则会将资源放回pool中,便于下次继续使用,为空则真正的进行close的操作,直接将Socket关闭了。而这两个if/else的逻辑是封装在一个方法中,不跟进来不会发现区别对待。

而且我们当前在用连接池,预期是按连接池的思路,使用完毕的需要释放回池中继续下次的使用,当前这个现象就比较怪异了。

继续向前,发现整体虽然Connection 使用的是JedisConnection,但在我们出问题的这里,返回的是个其子类JedisWrapper,这个是部门同学开发的一个SpringBoot 的 starter,重写了一部分逻辑,将连接对象作为原始对象持有,我们并没有用到其中的特性。上面判断dataSource是否为空本来是要判断JedisConnection里该属性是否为空,在Wrapper之后,是保存了origin的对象,返回的是个new Wrapper,这样dataSource并没有初始化,就出现了前面dataSource为空的问题。

跟到这里,发现是maven 的依赖不同,切换回标准的 SpringBoot starter,问题解决了。

小同学感叹道,「这不是造孽么,如果不是你帮我,不知道从哪下手分析了。」

我则鼓励小同学没有思路的时候,可以从源码里找找,跟代码的过程,也是学习的过程,比如这次就可以在跟的时候了解连接池具体是怎样实现的。任何问题在源码中都无处遁形,况且这些源码也可能有Bug呢。

回过头来,我们不难发现,可能不是所有的问题都需要跟源码,但阅读源码,带着问题 Debug,本身就像你放大招一样,虽然费时费力,但收获也会很多,一招制敌。这也是开源带来的好处,可能通过源码来分析作者的思路,在问题产生时可以逐行分析,了解细枝末节,这些都是C/C++里dll文件所不具备的优势。:-)

对于新同学,可能对于源码阅读有畏难情绪,感觉这一层层的嵌套,调用有点找不着头绪。但这些都是表象,你试着跟几次就轻车熟路了。

老司机为什么称为老司机,一是车技好,二是熟悉车况。这些也都是练出来的。

所以无论是做为解决问题的终极手段,还是学习设计与思想的宝库,源码都是不二之选,有时间的时候,可以多看看,不久之后,你也会是老司机。

最后,总结下一般出现问题时,跟源码的思路

  • 如果有异常,可以利用IDE的异常断点,这样异常产生时,一个鲜活的异常栈就获取到了,完整的调用链就在你眼前。
  • 逐级深入,先分块找到怀疑的目标方法,结合前一步,跟进
  • 具体方法时,不要根据表现的方法名,参数来猜方法的意图,必要时进去看一眼,万一有隐藏逻辑呢
  • 同样的类,看看包名、类名,是否是加载的类不对导致

【本文为51CTO专栏作者“侯树成”的原创稿件,转载请通过作者微信公众号『Tomcat那些事儿』获取授权】

戳这里,看该作者更多好文

【编辑推荐】

  1. 缓存这匹“野马”,你驾驭得了吗?
  2. T-Mobile事件告诉我们 美国企业如何响应数据泄露
  3. 数据库界的《延禧攻略》来了,不看你就输了
  4. 传统DBA将死?饿了么数据库自动化运维实践
  5. 机器学习=「新瓶装旧酒」的数据统计?No!
【责任编辑:赵宁宁 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢