源码面前,了无秘密

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

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

[[242307]]

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

是因为最近一个项目上线,其中有几个功能模块使用了 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那些事儿』获取授权】

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

责任编辑:赵宁宁 来源: 51CTO专栏
相关推荐

2021-09-16 10:36:34

开源技术 项目

2012-05-11 09:45:07

海量数据

2012-07-10 14:15:42

前端开发

2011-07-05 10:41:17

webOS

2020-02-05 09:27:23

疫情大数据大数据应用

2015-09-08 10:42:07

七牛大数据

2020-02-01 07:32:22

疫情远程办公互联网

2022-06-30 10:24:51

WiFi 7网络WiFi

2009-12-22 15:39:56

多核处理器

2021-07-27 22:51:22

互联网灾害技术

2009-02-17 23:51:57

Linux程序登录界面

2023-04-26 08:18:48

FormPrompt表单更改

2021-02-21 10:26:41

人工智能AI机器学习

2011-04-27 09:55:07

2021-05-31 20:48:45

人工智能AI无人机

2017-05-16 09:56:44

2023-07-31 07:25:27

2013-08-13 09:54:03

.NetJavaJava 8

2013-08-05 15:11:15

2011-07-25 09:19:00

CDP虚拟化
点赞
收藏

51CTO技术栈公众号