将Erlang Shell作为守护进程/服务运行

5

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

这就是我想要的:

  • 当机器启动时,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


你看到 rebar 了吗?https://bitbucket.org/basho/rebar/wiki/Home - Sergey Miryanov
3个回答

3
您需要做的是创建一个目标系统。关于如何创建目标系统的文档在这里:http://www.erlang.org/doc/system_principles/create_target.html。然而,一开始会有点复杂,直到您掌握基本概念。
大致上,您需要执行以下步骤:
  1. 创建一个空节点。也就是'bin, erts and releases'目录(带有更新的bin脚本)。
  2. 按照文档描述使用release_tools创建一个发行版。
  3. 在空节点上解压发行版,并设置release/start_erl.data指向新的发行版和erts版本。
然后,您可以将其作为服务进行管理,包括重启、监视等等。

现在,我建议使用relx - 它可以大大简化操作:https://github.com/erlware/relx - David N. Welton

3
除了按照@Martin的建议创建目标发布和标准的Erlang生产环境之外,你还需要以下内容:
  • To allow for automatic restart of a crashed node, you should use the heart functionality.

  • To stop a running Erlang node, you could start up a temporary Erlang node, connect to the running node and issue a stop command:

    erl -noshell -sname temp_control \
        -eval "rpc:call(mynode@myhost, init, stop, [])" \
        -s init stop
    
    • noshell disables input and shell output
    • sname sets the name for the temporary node
    • eval let's you execute any valid Erlang expression
      • rpc:call(Node, M, F, A) will call M:F(A) on the node specified (A is list of arguments that will be passed to the function as real arguments)
    • s M F runs the function M:F()

    (eval and s are run in sequence)


当我这样做时,我收到以下信息: 来自未被允许的节点temp_control@ubuntu的连接尝试 不过我还没有弄清楚如何创建目标系统...我对Erlang的理解还不够好:( - red-nuht
没事了,我解决了,它们需要使用相同的 cookie 启动 :) - red-nuht
是的,创建目标系统非常困难和复杂。请查看马丁的答案(以及我的评论),了解该主题的一些基本入门知识。 - Adam Lindberg
事实上,编写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 - red-nuht
1
如果您有其他问题,最好创建单独的问题。 - Adam Lindberg

2
最近发布的erld项目是真正将Erlang应用程序守护化的绝佳方式。它提供了所有守护进程所需的支持,包括:
  • 可以从init脚本启动/停止
  • 在启动时,控制台不会返回,直到程序成功启动(或无法启动)。
  • 启动诊断信息可以打印到控制台以指示进度,但一旦守护进程运行,输出就会停止。
  • 返回控制台时,返回代码指示成功(0)或失败(其他数字)。
  • 可以通过发送SIGHUP来触发日志轮换
请查看他们的github页面:https://github.com/ShoreTel-Inc/erld

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接