【问题标题】:Debugging Erlang heart timeouts调试 Erlang 心脏超时
【发布时间】:2011-04-18 00:15:21
【问题描述】:

我使用heart 程序在 Erlang 节点无响应时重新启动它。但是,我发现很难理解 为什么 节点会冻结。 SASL 日志没有显示任何错误,而我自己的日志似乎也没有显示当时发生的任何异常情况。任何人都可以提供有关调试此类事情的建议吗?

【问题讨论】:

    标签: erlang heartbeat


    【解决方案1】:

    默认情况下,heart 程序会发出一个SIGKILL 来杀死无响应的虚拟机,以便它可以快速启动一个新虚拟机。这使得几乎不可能获得有关 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, "

    如您所见,使用此补丁后,heart 将首先发出SIGUSR1 以尝试让 VM 创建故障转储。由于这可能需要一段时间,因此心脏会休眠 4 秒。如果您没有获得完整的故障转储,您可能必须增加此睡眠时间。之后,heart 尝试两次发出SIGQUIT 以希望获得核心转储,如果失败,则发出SIGKILL

    请注意,由于等待故障转储和核心转储所需的时间,此补丁会减慢 heart 的 VM 重启速度。如果您在生产中使用它,请注意此限制。

    【讨论】:

      【解决方案2】:

      您可以尝试从您的HEART_COMMAND 调用erlang:halt/1,从而从无响应的节点创建故障转储。

      您可以尝试使用erl_call 工具,例如-a erlang halt 123.

      如果 erlang 节点无法响应这也是有趣的信息。

      您是否尝试增加 `HEART_BEAT_TIMEOUT?也许节点只是有点卡住了,错过了超时但没有冻结。

      【讨论】:

      • 我做了(因为我希望是这样),但它似乎确实冻结了。
      【解决方案3】:

      如果您知道它冻结的原因,您可以尝试使用 dbg 跟踪模块。

      http://www.erlang.org/doc/man/dbg.html

      总之试试

      dbg:tracer(), dbg:p(all,c), dbg:tpl(Module, Function, x).
      

      如果您想停止此跟踪问题

      dbg:ctpl()
      

      有关详细信息,请参阅文档。

      注意:将 Module 和 Function 更改为您想要跟踪的任何内容,保持 x 不变。你也可以跳过Function,只给出Module, x。

      警告:在实时系统上运行此程序可能很危险,因为要打印到 shell 的信息量可能非常巨大。

      【讨论】:

      • 很遗憾,这行不通,因为我无法预测什么时候它会冻结。
      • 您可以设置dbg 跟踪到文件。让它运行一段时间可能会起作用,并且只有在检测到故障情况后才检查跟踪。
      • 它挂起的另一个可能原因是您的代码中有任何不包含超时的接收子句。查找它并向它们添加超时子句并记录错误。
      • 那不是只会挂一个进程,而不是整个节点吗?
      • 不错,那你怎么知道节点挂了呢?你有什么症状?
      猜你喜欢
      • 1970-01-01
      • 2012-03-22
      • 1970-01-01
      • 1970-01-01
      • 2012-03-16
      • 2018-04-25
      • 2020-12-12
      • 2014-05-12
      • 2018-09-20
      相关资源
      最近更新 更多