生产Elixir / Phoenix应用程序占用CPU

时间:2017-02-10 07:58:44

标签: elixir phoenix-framework cowboy

我有Elixir / Phoenix在生产中运行,一段时间后,其中一个beam.smp进程转为100%CPU负载(有时多于一个进程)。我不知道任何引发这种情况的触发器。我怎样才能知道发生了什么?

编辑:

我在服务器上运行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:init个条目。但是为什么......我怎么能阻止/预防/调试呢?

1 个答案:

答案 0 :(得分:3)

cowboy_protocol:init开头的进程是处理HTTP请求的进程。高减少计数表明它们陷入某种无限循环 - 两个进程似乎都在执行相同的功能 - 这个函数出错的可能性极高。

尾部位置的无限循环不消耗任何额外的内存 - 仅CPU。这是一个非常重要的特性 - 也就是GenServer的工作原理 - 尾部位置的无限循环,因此编译器(或运行时)无法区分使用此模式的错误代码和正确代码。

这也是对Erlang / Elixir称赞的“容错”的致敬 - 即使在程序的一个分支中存在无限循环,其余功能完全正常,及时响应请求。很少有平台能够做到这一点。