Недостаточно памяти для анализа XML-ответа SOAP в Rails с помощью Savon и Nokogiri - PullRequest
0 голосов
/ 10 марта 2019

У меня есть веб-приложение rails 4, которое использует конечную точку веб-службы SOAP.Для каждой компании отправляет запрос на получение списка ресурсов (неважно, какого рода, только информация).

Метод отправляет запрос с помощью Savon 2, получает ответ и анализирует его с помощью Nokogiri для обработки ресурсов XML с помощью xpath.

Цикл работает отлично, пока не попытается получить конкретную компанию.с очень большим количеством ресурсов, намного больше, чем другие.Тогда проблемы приходят.Я отслеживал с помощью top в Ubuntu, что, когда процесс начинает обрабатывать ответ, процесс использует оперативную память, пока не убьет приложение rails.Затем память освобождается, но веб-приложение не работает.

Пожалуйста, найдите пример кода внутри метода:

# 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".Затем веб-приложение рушится.

Какой, по вашему мнению, лучший подход?1. Есть ли лучший способ обработать эту информацию, избегая уничтожения приложения.2. Может быть, есть способ обработать ответ частично?3. Есть ли лучшие инструменты производительности для этого сценария?4. Ничего из вышеперечисленного невозможно, и я просто могу увеличить оперативную память моей системы?У меня есть экземпляр Amazon AWS с 4 ГБ.

1 Ответ

0 голосов
/ 14 марта 2019

Я просто хотел бы объяснить, как я решил это, и мои идеи. Вероятно, лучший подход при разборе больших XML-файлов - использовать SAX-анализатор, который является комментарием, предложенным @dbugger. Он не загружает весь XML в память, и именно поэтому он решает проблему. Однако в моем случае есть два неудобства. Во-первых, для нас критична производительность, и парсеры SAX медленнее парсеров DOM. Во-вторых, у нас уже есть весь код с парсером DOM, и нам нужно все перестроить.

По этой причине мой подход - своего рода обход. Я просто разбил большой XML-файл на более мелкие части, чтобы его легче было обрабатывать парсером DOM.

На данный момент все работает нормально. Итак, похоже на работу. Если я обнаружу какие-либо проблемы, я буду обновлять здесь.

...