defer panic 异常捕获 golang中类似throw 重连机制
场景
- 一般用于网络连接,数据库连接等情况
代码
package main
import (
"flag"
"fmt"
"log"
"time"
)
var (
ImplementKey string
ImplementVersion string
)
func Register(h interface{}) {
// 模拟注册过程,可能会发生 panic
if ImplementKey == "" || ImplementVersion == "" {
panic("key or version is empty")
}
fmt.Println("Registered successfully:", h)
}
type handler struct{}
func (my *handler) initConnector() {
defer func() {
if err := recover(); err != nil {
log.Println("connector panic:", err)
time.Sleep(time.Second * 3)
go my.initConnector()
}
}()
ImplementKey = flag.Lookup("build_name").Value.String()
ImplementVersion = flag.Lookup("build_version").Value.String()
Register(my)
}
func main() {
// 定义命令行参数
flag.String("build_name", "", "Build name")
flag.String("build_version", "", "Build version")
flag.Parse()
h := &handler{}
h.initConnector()
fmt.Println("here")
// 防止主 goroutine 提前退出
time.Sleep(time.Second * 20)
}
流程图
graph TB
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A([开始]):::startend --> B(定义命令行参数):::process
B --> C(解析命令行参数):::process
C --> D(创建 handler 实例):::process
D --> E(调用 initConnector 方法):::process
E --> F(注册 defer 函数):::process
F --> G(设置 ImplementKey 和 ImplementVersion):::process
G --> H{ImplementKey 或 ImplementVersion 为空?}:::decision
H -- 是 --> I(触发 panic):::process
I --> J(执行 defer 函数):::process
J --> K(记录 panic 信息):::process
K --> L(等待 3 秒):::process
L --> M(重新调用 initConnector 方法):::process
M --> F
H -- 否 --> N(成功注册):::process
N --> O(退出 initConnector 方法, 执行 defer 函数):::process
O --> P(无 panic 情况 defer 函数正常结束):::process
P --> Q(打印 here):::process
Q --> R(主 goroutine 等待 20 秒):::process
R --> S([结束]):::startend
浙公网安备 33010602011771号