摘要:已经上线的项目,出现服务挂掉的情况。

介绍:该服务是专门做打印的,业务需求是生成PDF文件进行页面预览,主要是使用ItextPDF+freemaker技术生成一系列PDF文件,其中生成流程有:解析模板生成临时PDF文件--->在临时PDF文件上注入文本和签名域--->旋转页面--->合并生成的多个PDF文件--->删除全部临时文件。

由于该业务生成的文件只是用来预览,不做保存,所以需要生成后就要删除。而每次生成的文件都是放在一个临时文件夹下,临时文件夹一开始我是根据建议书ID创建的(此处是导致宕机的关键所在),由于业务是每个用户只会操作自己账户下的建议书,既不会出现多人操作同一个建议书,既建议书(ID)具有唯一性,所以临时文件夹就以建议书ID命名。但是页面在预览的时候还有个另存为的业务,预览和另存为都是调的同一个生成文件的接口,如果用户在预览还在加载的时候就去点击另存为,此时会有新的线程去做同样的操作。由于该接口操作很多文件,所以响应会有点慢,导致预览的线程正在处理生成的文件,而另存为的线程又去生成同样的文件,并且是在同一个文件夹内,此时可能会出现预览线程正在处理的文件突然被另存为线程生成的文件覆盖,或者由于预览线程已经生成同样的文件而另存为线程生成不了,在这一过程中导致了服务的宕机。

bug修复过程:

开始以为是文件流未关闭导致的内存溢出,从而导致服务宕机,但是通过监控发现内存充足,后来查看生产环境上宕机的日志,猜测是上面提到的原因。通过线程睡眠模拟复现宕机bug,经过几番尝试,终于复现了!

而这个bug的罪归祸首就是那个临时文件夹,仅仅修改临时文件夹随机生成即可。

针对服务宕机的更深的分析需要一些时间去处理,暂时由于时间问题不做分析!

freemarker 生成文件流 freemarker生成pdf_freemarker 生成文件流