我正在处理一个Ruby项目,需要使用用户的xsl样式表转换原始xml文档。
最近,我意识到我的用户的一些样式表有无限循环,导致我的应用程序崩溃,所以我添加了一些错误处理来防止此类事件发生。
rescue SystemStackError, NoMemoryError => e
puts "error caught #{e.inspect}"
当我在本地运行应用程序时,我能够成功地挽救这个错误,但当我使用相同的样式表将它部署到我的aws实例时,这个错误只在小文件(例如,约200KB的xml)中被捕获。
对于更大的xml(比如4MB),应用程序似乎被卡住了(它永远不会完成当前任务,也不会继续下一个任务)。
我以为我的aws实例没有足够的内存,但即使将其从t2.micro更改为t2.large(与我的本地机器具有相同的内存量),我的应用程序仍然会莫名其妙地被卡住。
我比较了本地机器和aws实例中的所有宝石,它们都有相同的版本。我正在使用Nokorigi(1.6.7)。
有人能给我一些建议吗?任何帮助都将不胜感激!
附言:我应该提到,出于绝望,我甚至添加了像这样的声明
rescue Exception => e
#log exception here
在我所有其他错误处理代码的末尾,希望能一窥问题。。。但遗憾的是,鬼魂仍然是匿名的,而且是致命的(
我找到了问题的原因,并想分享我学到的东西:
- 即使在抢救SystemStackError时,垃圾收集器也没有清理内存,内存泄漏最终导致生产实例停止工作
- 同样的内存泄漏也发生在本地,但因为我的本地机器的内存比我们的生产实例多得多,所以崩溃的时间要长得多(所以它一开始似乎在本地正常工作)
- "修复"是同时使用Nokogiri和Ruby-xslt-gem——Nokogiri漂亮地处理了大多数xsl转换,但当它失败时,Ruby-xslt gem似乎可以处理奇怪的情况。因此,在我的代码中,我首先尝试使用Nokogiri进行转换,如果失败,则在使用xslt进行转换时进行转换
希望这能有所帮助。:)