Post

susure监督树简要介绍

susure监督树简要介绍

什么是监督树

我觉得监控树就是一种以树的形式管理多个进程/线程/协程(后面统一说进程)的程序设计模型。这一种模型基于 worker 和 supervisor 的思想。

  • worker 就是用于工作的进程。

  • supervisor 就是用于监控 worker 的进程。supervisor 在某一个 worker 出问题的时候可以重新启动 worker。

典型的 Supervision Tree 如下图所示:

  • 方框代表着 supervisor

  • 圆框代表着 worker

  • 1 表示 one_for_one

  • a 表示 one_for_all

one_for_one vs one_for_all

前者表示 worker failed 的时候,它的 supervisor 只重启这一个 worker。适用于在同一层的 worker 互不依赖的情况。

后者表示 worker failed 的时候,它的 supervisor 重启这一层的所有 worker。适用于同一层的 worker 互相依赖的情况。

在 Go 中如何应用

Supervision Tree 本是 Erlang 中的一个重要概念,但是有大佬把他移植到了 Go 上:https://github.com/thejerf/suture

https://pkg.go.dev/github.com/thejerf/suture/v4 这上面可以看到具体怎么使用。

具体用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package main

import (
    "context"
    "errors"
    "fmt"
    "github.com/thejerf/suture/v4"
    "time"
)

type SimpleServer struct {
    Name string
    Time time.Duration
}

func (s *SimpleServer) Serve(ctx context.Context) error {
    for {
        fmt.Println(s.Name)
        time.Sleep(s.Time)
    }
}

type ReturnErrorServer struct {
}

func (s *ReturnErrorServer) Serve(ctx context.Context) error {
    return errors.New("some stupid error")
}

type PanicServer struct {
}

func (s *PanicServer) Serve(ctx context.Context) error {
    panic("panic")
    return nil
}

func main() {
    ctx := context.TODO()
    r := suture.New("root", suture.Spec{})
    s1 := &SimpleServer{"s1", time.Second}
    s2 := &ReturnErrorServer{}
    s3 := &PanicServer{}
    r.Add(s1)
    r.Add(s2)
    r.Add(s3)
    _ = r.Serve(ctx)
}

可以看到不断输出 s1,supervsior 会尝试重启 s2 s3 一定次数。

This post is licensed under CC BY 4.0 by the author.