`
shangjava
  • 浏览: 1234636 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

找准目标再下手

阅读更多

好久没来这里写点啥了,总觉得没啥可以写的,今天来记个流水账说下上周遇见的一个比较低级的问题,按理来说一个老鸟不应该有这样的经验错误。

像往常一样,申请了一台测试用机,然后一系列配置,checkout 代码,开始build部署, 一切貌似都很顺利,检查服务器启动日志没有错误,正高兴着用url去访问一把,结果 呢,等10分钟,页面居然没有打开,一切都在进行中..... 让我着实郁闷了一把,咋回事呢? 日志中没有任何错误出现,习惯性的top命令查看了一下

基本上没load,cpu基本上完全空闲,内存也足够,NND,见上帝了?于是,我又重新更新了主干代码,重新build、重启服务器,再来,涛声依旧....

难道是启动代码什么地方有问题?于是加上-Xdebug 等参数准备调试一下,看代码有啥问题(说实话,一来就这么做的确还是有点傻,因为我都不能确定问题的大概范围就开始debug了,除了一步一步找代码,继续浪费时间,没有啥收获)折腾了半个小时,没有下文...,没辙了,去趟WC先,正欲起身,突然想起来,难道是主线程被阻塞了,导致不能响应请求?于是马上坐下,输入ps aux|grep java 找到进程号,再jstack 进程号|grep "main" ,我的目的是找到main这个主线程,一看果然

主线程一直在waiting,一看让其waiting的是DefaultUUCacheService中95行位置,

解释一下,我猜测了下这段代码的存在的原作者本来意图,该service初始化时,调用subCacheConfig()注册一个cache,注册完毕后,会等待中心配置服务器将一些cache配置推送到本机, 这是一个callback的异步通知过程,主线程继续向下走,它在继续向下执行之前必须确定cache配置已经准备好,于是使用了cacheReady这个 java.util.concurrent.atomic.AtomicBoolean 变量, 在callback成功后,将该变量设置成true,主线程会在这里循环get,看变量是否设置好,设置后了再继续,如果没有设置好,那么最多重试60次,也就是这里的tryTimes,杯具的是,这里没有对tryTimes 拿入判断中,导致一直要等待这个变量的设置完毕,一旦callback出问题,主线程也就挂在这里了,bug一个,最简单修改方法:while(!cacheReady.get()&&tryTimes>0){ .....}

不过问题又来了,什么东东会导致原本是好好的callback过程,而这里却一直出问题呢?于是在callback里外打上断点(这个时候才是比较有目的性的debug),结果发现 在开始配置服务器的时候将一个version给设置错了,导致拿不到数据,又没有任何异常出现,导致纠结了如此之久,还好误打误撞的错配置纠出了老代码中的bug,也算是没有白费功夫。


注: 代码出现问题,不要一开始漫无目的一开始上来就一通debug,这样目标范围太大,也基本上没有什么效果,而应该采取其他办法将问题范围缩小,找到问题发生的最可能根源再动手debug,本人之前一来就烦了. 这个大忌,导致时间白白浪费不少,教训。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics