我有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
个条目。但是为什么......我怎么能阻止/预防/调试呢?
答案 0 :(得分:3)
以cowboy_protocol:init
开头的进程是处理HTTP请求的进程。高减少计数表明它们陷入某种无限循环 - 两个进程似乎都在执行相同的功能 - 这个函数出错的可能性极高。
尾部位置的无限循环不消耗任何额外的内存 - 仅CPU。这是一个非常重要的特性 - 也就是GenServer的工作原理 - 尾部位置的无限循环,因此编译器(或运行时)无法区分使用此模式的错误代码和正确代码。
这也是对Erlang / Elixir称赞的“容错”的致敬 - 即使在程序的一个分支中存在无限循环,其余功能完全正常,及时响应请求。很少有平台能够做到这一点。