2011-03-30 93 views
1

我有一個one_for_one負責處理類似和完全獨立的孩子。如何才能達到max_restart_intensity主管刪除違規的孩子?

當有一個孩子有問題,多次出現故障和觸發:

=SUPERVISOR REPORT==== 30-Mar-2011::13:10:42 === 
    Supervisor: {local,gateway_sup} 
    Context: shutdown 
    Reason:  reached_max_restart_intensity 
    Offender: [{pid,<0.76.0>}, ... 

自行關閉,並終止所有無辜的孩子,只會繼續以優良否則運行。

如何用標準的Erlang監督員構建一個監督樹,只停止重新啓動一個違規的孩子並讓其他人獨處?

我在想有一個額外的主管只有一個孩子,但這似乎對我來說很重。

任何其他方式來處理?

+0

額外的上司也只是將這一問題進一步下跌。它仍然會崩潰,然後崩潰頂級主管。在這種情況下,只需增加最大重啓次數和最大時間值... – 2011-03-30 11:56:57

+0

@Adam:我需要停止重新啓動孩子,因爲它似乎阻止我與主管通話。所以我真的希望它停止重新開始犯錯的孩子,但不要終止其他人。我希望這可以在不寫我自己的主管的情況下實現。 – 2011-03-30 12:14:17

+0

糾正我,如果我錯了,但我總結你的情況爲:你有一個完全獨立的孩子的主管,孩子們可以在運行時啓動或崩潰時超時,你想重新啓動每個孩子,並停止重新啓動行爲不當而不影響其他孩子? – 2011-03-30 12:37:25

回答

4

我認爲最好的解決辦法是有兩層監督。

一位主管爲每個想要運行的gen_server啓動一個主管+進程對。該主管配置有one_for_one策略和temporary子女。

在此管理員下運行的每個主管將正確配置MaxRMaxT值,一旦孩子行爲異常,將觸發該主管的崩潰。

當下級主管崩潰時,頂級主管「只是不在乎」。

當一個孩子(總堆大小)啓動時,主管消耗233個字節,所以內存消耗不應該成爲問題。

監督樹應該是這樣的:

supervisor_top 
    | 
    | 
    +------------------------+----- ... 
    |      | 
supervisor_1    supervisor_2 
restart temporary   restart temporary 
    |       | 
    gen_server_1    gen_server_2 
    restart transient   restart transient 
+1

我按照我的理解在答覆中添加了一個圖表。這是你的意思嗎? – 2011-03-30 12:58:14

+0

@Peer正是! :-) – 2011-03-30 13:19:32

+0

謝謝!順便說一句,此設置還可以避免由於supervisor_top被可能的重新啓動循環隔離而導致的通過重新啓動循環而阻塞監控程序的問題(http://stackoverflow.com/questions/5485402/does-supervisor-block-calls-while-restarting-children)中期監管者不會觸發利率限制。 – 2011-03-30 14:32:48