Mic*_*ael 11 erlang erlang-otp erlang-supervisor
我的问题是,除了在发布升级方案中,是否可以修改已经运行的主管的重启强度阈值,如果是,如何?
它从来没有出现过,但运行一个最初没有孩子的主管,以便另一个进程通过主管启动子进程:start_child/2,所以我的sup init/1是这样的:
init([]) ->
RestartSt = {simple_one_for_one, 10, 10},
ChSpec = [foo, {foo,start_link,[]}, transient, 1000, worker, [foo]}],
{ok, {RestartSt, ChSpec}}.
Run Code Online (Sandbox Code Playgroud)
在主管开始时,可能的孩子数量是未知的; 当然它可以从10到10,000或更多变化很大.
20岁的重启强度对于10个孩子来说足够慷慨,但对于说10,000个孩子,我希望能够增加它...并且随着孩子数量因正常终止而下降而减少.
没有用于执行此操作的API,因此我相信您仍然坚持升级方法,除非您想通过提交拉取请求向OTP团队提出新的API,提供包含代码更改,新测试和文档的完整补丁变化.
还有一种非常肮脏的黑客方式,这涉及操纵内部管理员状态,所以我绝对不会建议生产系统,但我认为它仍然很有趣.甲supervisor存储重新启动强度在其内部循环的状态.您可以通过调用sys:get_state/1,2主管进程来查看此状态.例如,这是Yaws Web服务器中主管的状态:
1> rr(supervisor).
[child,state]
2> sys:get_state(yaws_sup).
#state{name = {local,yaws_sup},
strategy = one_for_all,
children = [#child{pid = <0.67.0>,name = yaws_sup_restarts,
mfargs = {yaws_sup_restarts,start_link,[]},
restart_type = transient,shutdown = infinity,
child_type = supervisor,
modules = [yaws_sup_restarts]},
#child{pid = <0.42.0>,name = yaws_server,
mfargs = {yaws_server,start_link,
[{env,true,false,false,false,false,false,"default"}]},
restart_type = permanent,shutdown = 120000,
child_type = worker,
modules = [yaws_server]},
#child{pid = <0.39.0>,name = yaws_trace,
mfargs = {yaws_trace,start_link,[]},
restart_type = permanent,shutdown = 5000,
child_type = worker,
modules = [yaws_trace]},
#child{pid = <0.36.0>,name = yaws_log,
mfargs = {yaws_log,start_link,[]},
restart_type = permanent,shutdown = 5000,
child_type = worker,
modules = [yaws_log]}],
dynamics = undefined,intensity = 0,period = 1,restarts = [],
module = yaws_sup,args = []}
Run Code Online (Sandbox Code Playgroud)
初始rr命令从中检索记录定义,supervisor以便在从中获取状态时可以看到字段名称yaws_sup,否则我们只会得到一个充满匿名值的元组.
检索到的状态在这种情况下显示强度为0.我们可以使用sys:replace_state/2,3以下方法更改它:
3> sys:replace_state(yaws_sup, fun(S) -> S#state{intensity=2} end).
#state{name = {local,yaws_sup},
strategy = one_for_all,
children = [#child{pid = <0.67.0>,name = yaws_sup_restarts,
mfargs = {yaws_sup_restarts,start_link,[]},
restart_type = transient,shutdown = infinity,
child_type = supervisor,
modules = [yaws_sup_restarts]},
#child{pid = <0.42.0>,name = yaws_server,
mfargs = {yaws_server,start_link,
[{env,true,false,false,false,false,false,"default"}]},
restart_type = permanent,shutdown = 120000,
child_type = worker,
modules = [yaws_server]},
#child{pid = <0.39.0>,name = yaws_trace,
mfargs = {yaws_trace,start_link,[]},
restart_type = permanent,shutdown = 5000,
child_type = worker,
modules = [yaws_trace]},
#child{pid = <0.36.0>,name = yaws_log,
mfargs = {yaws_log,start_link,[]},
restart_type = permanent,shutdown = 5000,
child_type = worker,
modules = [yaws_log]}],
dynamics = undefined,intensity = 2,period = 1,restarts = [],
module = yaws_sup,args = []}
Run Code Online (Sandbox Code Playgroud)
我们的第二个参数sys:replace_state/2将状态记录作为参数并将其intensity字段更改为2. sys:replace_state/2,3函数返回新状态,正如您在此处看到的结果的末尾,intensity现在是2而不是0.
正如sys:replace_state/2,3文档所解释的那样,这些函数仅用于调试目的,因此在生产系统中使用它们绝对不是我推荐的.这里的第二个参数replace_state表明这种方法需要知道supervisor我们通过rrshell命令获得的内部状态记录的细节,所以如果该记录发生变化,这段代码可能会停止工作.更加脆弱的是将supervisor州记录视为一个元组,并指望它intensity字段位于特定的元组位置,因此您可以更改其值.因此,如果你真的想要这个改变主管重启强度的功能,那么从长远来看,你最好向OTP团队提出它被添加的内容; 如果您打算采取这种方式,我建议首先在erlang-questions邮件列表上提出这个想法来衡量兴趣.
| 归档时间: |
|
| 查看次数: |
461 次 |
| 最近记录: |