使用Savon和Nokogiri在Rails中解析XML SOAP响应的内存不足

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Savon和Nokogiri在Rails中解析XML SOAP响应的内存不足相关的知识,希望对你有一定的参考价值。

我有一个使用SOAP Web服务端点的rails 4 webapp。对于每个公司,发送一个获取资源列表的请求(不管是什么类型,只是信息)。

该方法使用Savon 2发送请求,获取响应并使用Nokogiri解析它以使用xpath处理XML资源。

循环工作很好,直到它试图获得具有大量资源的特定公司,远远超过其他公司。然后,问题来了。我在ubuntu中使用'top'进行监控,当进程开始处理响应时,进程占用RAM内存,直到它杀死rails应用程序。然后内存被释放但webapp下降了。

请在方法中找到示例代码:

# Initializing Savon client
client = Savon.client(wsdl: endpoint, 
                      log_level: :info,
                      log: true,
                      pretty_print_xml: true,
                      open_timeout: 300, 
                      read_timeout: 300)
for company in companies do
  message = {'in0' => USER_ID, 
             'in1' => USERNAME, 
             'in2' => MMK_PASSWORD,
             'in3' => company.id}
  @logger.debug "getResources=1"
  response = client.call(:get_resources, message: message) 
  @logger.debug "getResources=2"               
  resourcesXML = response.to_hash[:get_resources_response][:out]
  @logger.debug "getResources=3"              
  resourcesParsed = Nokogiri::XML(resourcesXML)
  @logger.info "getResources=4"
  resources = resourcesParsed.xpath("//resource")
  @logger.info "getResources=5"

日志显示为“getResources = 3”。然后webapp粉碎了。

您认为最好的方法是什么? 1.有没有更好的方法来处理这些信息,避免杀死应用程序。 2.也许有办法部分处理答案吗? 3.这种情况是否有更好的性能工具? 4.以上都不可能,我只能增加系统的RAM?我有一个4GB的亚马逊AWS实例。

答案

我只是想解释一下我是如何解决它和我的见解的。解析大型XML文件时,最好的方法可能是使用SAX解析器,这是@dbugger建议的注释。它没有将整个XML加载到内存中,这就是它解决问题的原因。但是,在我的情况下有两个不便之处。首先,性能对我们至关重要,SAX解析器比DOM解析器慢。第二个是我们已经拥有了DOM解析器的所有代码,我们需要重新开发所有东西。

出于这些原因,我的方法是一种解决方法。我只是通过DOM解析器更容易地将较大的XML文件拆分为较小的部分。

目前,它工作正常。所以,它看起来很有效。如果我发现任何问题,我会在这里更新。

以上是关于使用Savon和Nokogiri在Rails中解析XML SOAP响应的内存不足的主要内容,如果未能解决你的问题,请参考以下文章

Nokogiri / Rails / zlib1g-dev的问题

如何在 Nokogiri 中解析图像 href

如何使用 Nokogiri 解析 HTML 表格?

Rails -nokogiri GEM:检测 URL 中图像的 MIME 类型

将 Nokogiri 文档转换为 Ruby 哈希

ruby on rails - 问题捆绑安装nokogiri 1.7.2 on ruby on rails 4.x.