【问题标题】:Running erlang shell as a daemon/service将 erlang shell 作为守护程序/服务运行
【发布时间】:2011-10-13 10:25:18
【问题描述】:

显然,我有一个在 Erlang shell 中运行的 Erlang 程序,我想监控它。

这就是我想要的:

  • 当机器启动时,Erlang shell 应该随之启动,运行在 shell 中的程序也应该启动。
  • 如果 Erlang shell 因某种原因崩溃,它应该重新启动。
  • 您应该能够手动启动/停止/重新启动 Erlang shell。

例子:

/etc/init.d/foobar start
/etc/init.d/foobar stop
/etc/init.d/foobar restart

我还没有开始整个“如果崩溃则重新启动”的事情,被简单的事情卡住了,还是很容易?

我所做的是这样的:

从 /etc/init.d/skeleton 中获取骨架代码并替换 PATH、DESC、NAME 等...这行得通,我可以做到:

/etc/init.d/foobar start

但是,我无法阻止它...问题是我用“erl”启动了 Erlang shell,这是一个脚本,可以做一些我不明白的花哨的事情。它所做的一件事是,它创建了一个非常长且复杂的进程名称。这不仅仅是“erl”,它就像:

/usr/lib/erlang/erts-5.7.4/bin/beam.smp -- -root /usr/lib/erlang -progname erl -- -home /home/xxx -- .... 还有一些更多。

有没有更好的方法来做到这一点?

操作系统:Ubuntu 11.04

【问题讨论】:

标签: bash erlang daemon


【解决方案1】:

最近发布的 erld 项目是真正守护 Erlang 应用程序的绝佳方式。它为守护进程应该做的所有事情提供支持,即:

  • 可以从初始化脚本启动/停止
  • 在启动时,控制权不会返回到控制台,直到程序成功启动(或启动失败)。
  • 可以将启动诊断信息打印到控制台以指示进度,但一旦守护程序运行,输出就会停止。
  • 返回控制台时,返回代码指示成功 (0) 或失败(其他数字)。
  • 可以通过发送 SIGHUP 触发日志轮换

在此处查看他们的 github 页面:https://github.com/ShoreTel-Inc/erld

【讨论】:

    【解决方案2】:

    您要做的是创建一个目标系统。这样做的文档在这里:http://www.erlang.org/doc/system_principles/create_target.html 但是,一开始有点复杂,直到你掌握了基本概念。

    粗略地说,您执行以下操作:

    1. 创建一个空节点。也就是说,“bin、erts 和 release”目录(在 bin 中包含更新的脚本)。
    2. 如 dox 中所述,通过 release_tools 创建版本。
    3. 在空节点上解压release,设置release/start_erl.data指向新的release和erts版本。

    然后可以将其作为服务进行管理,包括重启/监视器以及您想添加的任何内容。

    【讨论】:

    【解决方案3】:

    除了创建目标版本,@Martin 推荐的标准 Erlang 生产环境,您还需要以下内容:

    • 要允许自动重启崩溃的节点,您应该使用the heart functionality

    • 要停止正在运行的 Erlang 节点,您可以启动一个临时 Erlang 节点,连接到正在运行的节点并发出停止命令:

      erl -noshell -sname temp_control \
          -eval "rpc:call(mynode@myhost, init, stop, [])" \
          -s init stop
      
      • noshell 禁用输入和 shell 输出
      • sname 设置临时节点的名称
      • eval 让你执行任何有效的 Erlang 表达式
        • rpc:call(Node, M, F, A) 将在指定的节点上调用 M:F(A)A 是将作为实际参数传递给函数的参数列表)
      • s M F 运行函数M:F()

      evals 依次运行)

    【讨论】:

    • 当我这样做时,我得到: ** 来自不允许的节点 temp_control@ubuntu 的连接尝试 ** 虽然我还没有弄清楚如何创建目标系统......我的 erlang 不够好明白了:(
    • Nvm 我解决了这个问题,它们需要使用相同的 cookie 启动 :)
    • 是的,创建目标系统是出了名的困难和复杂。请查看 Martin 的回答(附上我的评论),了解有关该主题的一些基本入门知识。
    • 问题是不是我写了erlang代码,我只是被要求为它创建一个脚本。但是我有另一个关于 erlang 的问题:我创建了一个临时节点,它对主节点执行 rpc,该函数返回一个我想打印出来的元组。元组看起来像这样:{ok,["1234"]},但是当我尝试使用 io:write 打印它时,它看起来像这样:{ok,[[49,50,51,52]]}。为什么是这样?我只想打印 rpc 调用返回的内容?我想在命令行中这样做: erl -noshell -sname temp -setcookie uep1 -eval 'io:write(rpc:call(A,B,C)' -s init stop
    • 如果您有任何其他问题,最好创建单独的问题。
    最近更新 更多