这个项目最初我是PM,当时要求集群达到60000tps,单服务器要能达到2000tps,这个要求说实话的确有些夸张,最终结果虽然没这么高,但单台服务器主要流程的确能达到近1000tps,这不是重点。我负责的项目交付一期之后,交给另一位同事继续后续的二期的开发,这个项目后续在甲方重视程度很高,至今仍有大量人力在支持这个项目。有一天这个项目的PM给我打电话,说最近系统出现一个奇怪的现象,很是小的几率会出现500错误,一旦出现错误之后,再访问都是500错误,只有重启才能解决,cpu和内存使用率都很是的低,没有任何的错误日志,他们已经分析了几天了,一点儿思路也没有,今天又出现了。tomcat
之前看这这样一句话“全部没有日志的问题定位都是耍流氓”,可是现实状况就是不耍流氓就不行,问题摆在面前。服务器
6点吃过晚饭和同事一块儿到了客户的办公场所,由于这是我以前负责的项目,里面的流程和代码我比较熟悉,可是一时也没有思路,惟一的思路就是这个500页面,灵光一现,能不能在这个500页面里作文章,由于我知道在j2ee中会在request和session的attribute写一些属性,会不会这里有一些线索。因而我在这台出现500错误的jsp页面里面加了一堆把request和session里全部的attribute都读出来的代码,这下子信息量就大了不少,发现了在attribute有一个error,一步步的推断是底层的平台抛出的错误,再进一步结合代码反编译发现是咱们使用的底层平台在使用线程变量的时候在异常处理的时候没有将ThreadLocal的值清空致使后面再进来的请求读取的是空对象,也也致使了NPE,这样推测下咱们找到了平台的同事一块儿分析,他们在Review代码之后也认可有问题,很快他们修复了bug,至此再没出现过。session
这个问题自己从技术来说并无太多好玩的东西,可是让我更加坚信问题总有解决的办法,更加全面的掌握各类知识加上实践会让你在遇到问题有更多的机会会灵光一现。问题自己并无太多的技术含量,可是当你去解决的时候,你会发现若是没有经验和知识储备的话,解决起来步履维艰。jsp
有的人可能会问为何NPE的日志为何会被吃掉了,而不是打印在tomcat的默认的日志中,这是由于这个项目中把标准错误输出和标准输出都重定位到/dev/null这个垃圾桶中了. 线程