6

我有一个具有两个工作进程的主管:一个处理与远程服务器的连接的 TCP 客户端和一个处理连接协议的 FSM。

在子进程中处理 TCP 错误会使代码变得非常复杂。所以我宁愿“让它崩溃”,但这有一个不同的问题:当服务器无法访问时,将很快达到最大重启次数,并且主管将与我的整个应用程序一起崩溃,这对于我来说是非常不可取的这个案例。

我想要的是有一个带回退的重启策略;init否则,如果主管知道何时因崩溃而重新启动(即,它作为参数传递给函数)就足够了。我找到了这个邮件列表线程,但是有没有更官方/更好测试的解决方案?

4

3 回答 3

6

我在使用 erlang 时遇到过这个问题很多次,并尝试了很多解决方案。我认为我发现的最好的方法是有一个由主管启动并启动可能崩溃的额外进程。

它在启动时启动孩子,等待孩子退出并重新启动孩子(有延迟)或适当退出。我认为这比回退服务器(您链接到的)更简单,因为您只需要保留有关单个孩子的状态。

我使用的另一个解决方案是必须将子进程作为瞬态启动,并有一个单独的进程来轮询并重新启动任何已崩溃的进程。

于 2010-09-24T10:17:12.463 回答
6

您可能会发现我们的主管垫是一个很好的起点。我使用它来减慢必须运行的东西的重启速度,但在启动时会很快失败(例如遇到资源问题的端口)。

于 2010-09-24T19:03:55.853 回答
2

因此,首先您想通过 process_flag(trap_exit, true)在您的 init 中使用 a 来捕获孩子的提前终止。

然后您需要决定您希望将重启延迟多长时间,例如 10 秒,在

handle_info({'EXIT', _Pid, Reason}, State) ->
    erlang:send_after(10000, self(), {die, Reason}),  
    {noreply, State};

最后,让进程随着

handle_info({die, Reason}, State) ->
    {stop, Reason, State};
于 2017-12-27T17:45:46.967 回答