Приложение Production Elixir / Phoenix загружает процессор

У меня работает Elixir / Phoenix, и через некоторое время один из процессов beam.smp переходит на 100% загрузку ЦП (иногда более одного процесса). Я не знаю ни одного триггера, вызывающего это. Как я могу узнать, что происходит?

РЕДАКТИРОВАТЬ:

Я запустил iex на сервере и подключился к узлу Phoenix. Затем я запустил etop и получил следующий результат:

Load:  cpu       100               Memory:  total       69429    binary      10568
        procs     303                        processes   16656    code        20194
        runq        1                        atom          727    ets          7205
Pid            Name or Initial Func    Time    Reds  Memory    MsgQ Current Function
----------------------------------------------------------------------------------------
<19947.645.0>  cowboy_protocol:init     '-'90164000   88736       0 'Elixir.MyApp.Error
<19947.902.0>  cowboy_protocol:init     '-'88696000   88744       0 'Elixir.MyApp.Error
<19947.242.0>  'Elixir.Redix.Connec     '-'   11697   24704       0 gen_server:loop/6
<19947.240.0>  Elixir.Exq               '-'   10284   24664       0 gen_server:loop/6
<19947.236.0>  Elixir.Exq.Redis.Cli     '-'    9597   34520       0 gen_server:loop/6
<19947.1695.0> etop_txt:init/1          '-'    6258  230504       0 etop:update/1
<19947.245.0>  Elixir.Exq.Scheduler     '-'    4831   24664       0 gen_server:loop/6
<19947.241.0>  'Elixir.Redix.Connec     '-'    2339    8856       0 gen_server:loop/6
<19947.426.0>  Elixir.MyApp.Presen      '-'     262  143160       0 gen_server:loop/6
<19947.238.0>  Elixir.Exq.Stats         '-'     105   42344       0 gen_server:loop/6
========================================================================================

Эти две cowboy_protocol:initentries вызывают проблему. Но почему ... и как его остановить / предотвратить / отладить?


person Philip Claren    schedule 10.02.2017    source источник


Ответы (1)


Процессы, запущенные с cowboy_protocol:init, - это процессы, обрабатывающие HTTP-запросы. Большое количество сокращений предполагает, что они застряли в каком-то бесконечном цикле - оба процесса, похоже, выполняют одну и ту же функцию - очень высока вероятность, что эта функция неисправна.

Бесконечный цикл в хвостовой позиции не требует дополнительной памяти - только ЦП. Это в значительной степени особенность - и именно то, как работает GenServer - бесконечный цикл в хвостовой позиции, поэтому компилятор (или среда выполнения) не имеет возможности отличить неправильный код от правильного, использующего этот шаблон.

Это также во многом дань похвальной «отказоустойчивости» Erlang / Elixir - хотя в одной ветви программы существует бесконечный цикл, остальные функционируют совершенно нормально, своевременно отвечая на запросы. Очень немногие платформы могут это сделать.

person michalmuskala    schedule 10.02.2017
comment
Я нашел для этого причину. У меня был шаблон, в котором был тег изображения с URL-адресом изображения, которого больше не существует, и я забыл обновить тег. Но как это может вызвать такое ?! - person Philip Claren; 11.02.2017
comment
Похоже, это вызывает каждый запрос к несуществующему изображению. Это не может быть нормально ... - person Philip Claren; 11.02.2017
comment
Вы смотрели на функцию, указанную в выводе etop как Текущая функция? Начало имени модуля имеет префикс MyApp, поэтому я предполагаю, что это ваш код. Скорее всего, это функция, в которой произошла ошибка. - person michalmuskala; 11.02.2017
comment
Я также обновил ответ, указав, что это не может быть нормальным утверждением - это очень похоже. - person michalmuskala; 11.02.2017
comment
В ответ на ваше последнее изменение: я распознал это поведение только потому, что мой сервер мониторинга сообщает об использовании процессора на 100%. Программа как всегда полностью откликалась, работала быстро и живо. Это восхитительно. Но, тем не менее, доступ к несуществующему активу / маршруту, вызывающий это, очень странный, не так ли? - person Philip Claren; 11.02.2017
comment
Последний комментарий по этому поводу: я начинаю подозревать, что AppSignal может работать некорректно в некоторых созвездиях. На данный момент я определил маршрут для приема всей почты домена в конце, который отвечает 404. - person Philip Claren; 14.02.2017
comment
Вы исследовали функцию, показанную в выводе etop? Я все вижу, но имя модуля начинается с MyApp.Error - скорее всего, это функция с бесконечным циклом. - person michalmuskala; 14.02.2017
comment
MyApp.Error - это не полное имя (я заменил фактическое имя приложения на MyApp, чтобы сделать его более понятным), а имя было усечено etop. Дело в том, что три модуля начинаются с MyApp.Error (ErrorView, ErrorController, ErrorHelpers), и я не знаю, какой из них вызывает проблему. Есть ли способ получить от etop более широкий выход? - person Philip Claren; 14.02.2017
comment
Не уверен, на самом деле я никогда не пользовался этопом. Вы можете получить доступ к необработанным данным о текущей функции, выполняемой процессом, с помощью Process.info(pid, :current_function). IEx имеет pid/3 помощника для создания pid, когда вы знаете числа, поэтому Process.info(pid(19947,645,0), :current_function) из IEx предполагает вывод, как в исходном сообщении. - person michalmuskala; 14.02.2017
comment
Это просто повторяется снова, и это MyApp.ErrorView.render/1. Я думаю, он не работает и вызывает себя? Я постараюсь вникнуть в это глубже. Но Process.info действительно помог найти этого маленького негодяя. - person Philip Claren; 19.02.2017