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

时间:2019-03-10 18:15:31

标签: ruby-on-rails soap nokogiri savon

我有一个正在使用SOAP Web服务端点的Rails 4 Web应用程序。对于每个公司,发送一个请求以获取资源列表(无论哪种类型,仅是信息)。

该方法使用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的Amazon AWS实例。

1 个答案:

答案 0 :(得分:0)

我只想解释我如何解决它以及我的见解。解析大型XML文件时,最好的方法可能是使用SAX解析器,这是@dbugger建议的注释。它不会将整个XML加载到内存中,这就是它解决问题的原因。但是,就我而言,有两个不便之处。首先,性能对我们至关重要吗?SAX解析器比DOM解析器慢。第二个是我们已经具有DOM解析器的所有代码,并且我们需要重新开发所有内容。

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

目前,它工作正常。因此,它看起来可以工作。如果发现任何问题,我将在这里更新。