生产 Elixir/Phoenix app hog CPU
Production Elixir/Phoenix app hogs CPU
我有一个 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
条目。但是为什么...我怎么能stop/prevent/debug呢?
以cowboy_protocol:init
开头的进程是处理HTTP请求的进程。高减少计数表明它们陷入了某种无限循环 - 两个进程似乎都在执行相同的功能 - 此功能出现故障的可能性极高。
尾部位置的无限循环不会消耗任何额外的内存 - 仅 CPU。这是一个非常重要的功能 - 以及 GenServer 的确切工作方式 - 尾部位置的无限循环,因此编译器(或运行时)无法区分使用此模式的错误代码和正确代码。
这里也非常感谢Erlang/Elixir的好评"fault tolerance"——虽然程序的一个分支存在死循环,但其余功能完全正常,及时响应要求。很少有平台能够做到这一点。
我有一个 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
条目。但是为什么...我怎么能stop/prevent/debug呢?
以cowboy_protocol:init
开头的进程是处理HTTP请求的进程。高减少计数表明它们陷入了某种无限循环 - 两个进程似乎都在执行相同的功能 - 此功能出现故障的可能性极高。
尾部位置的无限循环不会消耗任何额外的内存 - 仅 CPU。这是一个非常重要的功能 - 以及 GenServer 的确切工作方式 - 尾部位置的无限循环,因此编译器(或运行时)无法区分使用此模式的错误代码和正确代码。
这里也非常感谢Erlang/Elixir的好评"fault tolerance"——虽然程序的一个分支存在死循环,但其余功能完全正常,及时响应要求。很少有平台能够做到这一点。