Как отловить исключения Memory Quota у работника героки - PullRequest
6 голосов
/ 16 ноября 2011

Я использую delayed_job для обработки фоновых заданий с помощью heroku.Иногда я переступаю через выделение памяти и получаю такие вещи, как:

2011-11-16T02: 41: 25 + 00: 00 heroku [worker.1]: ошибка R14 (Превышен квот памяти) 2011-11-16T02: 41: 45 + 00: 00 heroku [worker.1]: процесс запущен mem = 542M (106,0%)

Я бы хотел элегантно с этим справиться.Есть ли способ узнать, когда я собираюсь пересечь предел моей памяти?

Что-то вроде rack-timeout было бы здорово

Спасибо!

Ответы [ 4 ]

6 голосов
/ 09 декабря 2011

Я думаю, что нашел хорошее решение для этого, украдя некоторый код из гема Oink . В частности это файл: memory_snapshot.rb , который вы должны прочитать. В нем изложены 4 различных способа использования памяти с ошибками

Так что на уровне стойки это невозможно, вам нужно добавить проверку памяти во время процесса, вызывающего проблему с памятью (в моем случае это был файл csv).

Итак, в этом цикле это выглядело примерно так:

  def build_string_io(collection)
    csv_io = StringIO.new
    csv_io << collection.first.to_comma_headers.join(',') + "\n"
    collection.each do |imp|
      csv_io << imp.to_comma.join(',') + "\n"
      check_memory!
    end
    csv_io.rewind
    csv_io
  end

  def check_memory!
    raise 'AboutToRunOutOfMemory' if memory > 400.megabytes #Or whatever size your worried about
  end


  # Taken from Oink
  def memory
     pages = File.read("/proc/self/statm")
     pages.to_i * self.class.statm_page_size
  end

  def self.statm_page_size
      @statm_page_size ||= begin
      sys_call = SystemCall.execute("getconf PAGESIZE")
      if sys_call.success?
        sys_call.stdout.strip.to_i / 1024
      else
        4
      end
    end
  end
2 голосов
/ 09 декабря 2011

У вас проблема в том, что вам нужны данные, которые доступны только из журналов.

Лучшим подходом здесь будет использование утечки системного журнала для отправки ваших журналов в службу, такую ​​как Papertrailapp.com илиLoggly - с помощью этих сервисов вы можете настроить поиск для вашей ошибки R14, но затем получать уведомления - Papertrail поддерживает костер, сообщения, электронные письма и т. Д., Где вы можете обработать ошибку.

Мы делаем этот точный процесс публикации в приложении sinatraтакже размещается в Heroku, где мы просматриваем записи журнала маршрутизатора heroku и очереди = размеры или для слишком глубоких ошибок в журнале, а затем автоматически масштабируем наши приложения, когда это требуется - потому что системный журнал почти в реальном времени, наши приложения, по сути, осознают себя.

1 голос
/ 05 июня 2013

Я использовал этот системный вызов, идея взята из этого сценария memory_snapsot.rb из драгоценного камня oink:

system("ps -o vsz= -p #{$$}")

Таким образом, у вас могут быть некоторые идеи об увеличении памяти и о том, где это может быть создано в вашем коде

1 голос
/ 09 декабря 2011

Проблема, с которой вы столкнулись, заключается в том, что когда вы получаете эту ошибку, вы уже выгружены из процесса Ruby, и платформа Heroku обрабатывает эту ошибку. Здесь вам не помогут начало, спасение, конец.

С точки зрения предвидения, вы можете посмотреть на объем свободной памяти, запустив что-то вроде:

memory = `free -m`

Затем вы можете проанализировать эти результаты, чтобы получить значимое состояние памяти. Однако я не уверен, что вы можете сделать с этой информацией.

(Помните, что dyno - это просто Unix Box, и вы можете запускать произвольные системные команды с Ruby, заключая команды в обратные метки)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...