監督樹(Supervision Tree)在 Go 中的應用

前言:看源碼遇到了一個監督樹的概念,好好探索一番

什么是監督樹

我覺得監控樹就是一種以樹的形式管理多個進程/線程/協程(后面統一說進程)的程序設計模型。這一種模型基于 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 這上面可以看到具體怎么使用。

具體用法

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 一定次數。

參考

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容