学艺不精,导致一个问题浪费了三个小时,在此记录下,警示自己:学海无涯,吾当不停努力!
起源
前段时间做了一个对接某信文件共享平台的接口,就是按照接口规范给他们平台上传文件。 系统采用springboot搭建,对外提供了一个restful接口,接口内容包含四部分:校验文件合法性、调用平台的上传通知接口获取ftp相关信息、调用ftp上传文件、调用平台的上传完成通知接口。 系统完成后交给实施人员部署,由实施人员采用curl定时调用接口,上传文件,仅此而已。
问题
实施人员测试无问题后,写了个shell脚本,每天定时上传一批文件,突然在一个美好的下午,实施人员发过来一个截图,大量的文件上传失败,大量报错:Can't start StopWatch: it's already running,心理瞬间不美好了。无奈,此功能比较重要,每天要好多文件上传,遂开始看错误,还好咱是英语过6级的人,一眼就看出来是StopWatch调用start方法的时候报错了,提示这个StopWatch已经处于running状态。心想,这不是so easy吗,肯定是SW没有stop啊,但是转念一想,我不会犯这个低级错误啊,走马观花看了一眼代码,确实也在最后stop了。又想其他原因,因为以前没问题,现在是shell脚本每隔10s调用一次,调用了很多次,心想不会是因为并发导致的把,依稀记得StopWatch是非线程安全的,立马想到应该是并发导致,遂暴力新增同步锁,打包升级,发现还是不行,这就慌了,不会啊,还是耐下心来仔细看代码吧,突然发现StopWatch是在方法里创建的,根本不会有并发问题,再仔细看代码,发现方法里有循环,循环里有业务判断,某些条件下直接continue,而我的stop方法是在最后执行的,如果continue就不会执行,恍然大悟,这么简单问题 由于粗心导致3个小时浪费了,这下找打问题就好说了,最后加个finally代码块,stop放到这里,打包升级,没问题了。
心得
- 出问题检查代码一定要仔细,在没有验证的情况下不要轻易下结论
- 方法里没有线程并发问题
- 仔细看日志、看日志、日志,这点很重要