我使用心脏程序在Erlang节点变得无响应时重新启动它。然而,我发现很难理解为什么节点冻结。SASL日志没有显示任何错误,我自己的日志似乎也没有显示在那些时候发生的任何值得注意的事情。谁能给点建议调试一下这种东西?
默认情况下,心脏程序发出一个SIGKILL
来杀死无响应的VM,以便它可以快速启动一个新的VM。这使得获取有关虚拟机的任何有用信息几乎是不可能的。我过去尝试过修补心脏程序以避免硬杀死,而不是让VM创建崩溃转储和核心转储。我使用了这样的补丁(这是Erlang/OTP R14B02):
--- erts/etc/common/heart.c.orig 2011-04-17 12:11:24.000000000 -0400
+++ erts/etc/common/heart.c 2011-04-17 12:12:36.000000000 -0400
@@ -559,10 +559,11 @@
int res;
if(heart_beat_kill_pid != 0){
pid = (pid_t) heart_beat_kill_pid;
- res = kill(pid,SIGKILL);
+ res = kill(pid,SIGUSR1);
+ sleep(4);
for(i=0; i < 5 && res == 0; ++i){
sleep(1);
- res = kill(pid,SIGKILL);
+ res = kill(pid,i < 2 ? SIGQUIT : SIGKILL);
}
if(errno != ESRCH){
print_error("Unable to kill old process, "
如您所见,使用此补丁心脏将首先发出SIGUSR1
以尝试让VM创建崩溃转储。因为这需要一段时间,所以心脏会睡4秒。如果你没有完全崩溃,你可能需要增加睡眠时间。在此之后,heart然后尝试两次发出SIGQUIT
,希望获得coredump,如果失败,则发出SIGKILL
。
请注意,由于等待崩溃转储和内核转储所需的时间,此补丁将减慢heart的VM重启速度。如果在生产环境中使用它,请注意这个限制。
您可以尝试从HEART_COMMAND
调用erlang:halt/1
,从而从无响应的节点创建崩溃转储。
您可以尝试使用erl_call
工具,例如-a erlang halt 123
.
如果erlang节点不能响应,这也是一个有趣的信息。
你试过增加' HEART_BEAT_TIMEOUT '吗?
如果您知道为什么它冻结,您可以尝试使用dbg跟踪模块。
http://www.erlang.org/doc/man/dbg.html简而言之
dbg:tracer(), dbg:p(all,c), dbg:tpl(Module, Function, x).
如果您想停止此跟踪问题
dbg:ctpl()
查看文档获取更多信息
注意:将模块和函数更改为您想要跟踪的任何内容,保持x不变。你也可以跳过Function,只给出Module, x.
警告:在活动系统上运行此命令可能是危险的,因为要打印到shell的信息量可能非常大。