golang优雅管理应用关闭信号的插件库Death的使用
Golang优雅管理应用关闭信号的插件库Death的使用
Death是一个简单易用的库,可以帮助你更好地管理应用程序的关闭信号。
获取库
使用以下命令获取最新版本的Death库:
go get github.com/vrecan/death/v3
使用库
基本用法
package main
import (
DEATH "github.com/vrecan/death/v3"
SYS "syscall"
)
func main() {
death := DEATH.NewDeath(SYS.SIGINT, SYS.SIGTERM) // 传入你想结束应用程序的信号
// 当你想要阻塞等待关闭信号时
death.WaitForDeath() // 当指定类型的信号发送到你的应用程序时,这个函数会结束
}
在关闭时关闭其他对象
Death的一个简单特性是它可以在关闭开始时关闭其他对象。
package main
import (
"log"
DEATH "github.com/vrecan/death/v3"
SYS "syscall"
"io"
)
func main() {
death := DEATH.NewDeath(SYS.SIGINT, SYS.SIGTERM) // 传入你想结束应用程序的信号
objects := make([]io.Closer, 0)
objects = append(objects, &NewType{}) // 只要类型实现了Close方法,这就能工作
// 当你想要阻塞等待关闭信号时
err := death.WaitForDeath(objects...) // 当指定类型的信号发送到你的应用程序时,这个函数会结束
if err != nil {
log.Println(err)
os.Exit(1)
}
}
type NewType struct {
}
func (c *NewType) Close() error {
return nil
}
使用匿名函数关闭
package main
import (
DEATH "github.com/vrecan/death/v3"
SYS "syscall"
)
func main() {
death := DEATH.NewDeath(SYS.SIGINT, SYS.SIGTERM) // 传入你想结束应用程序的信号
// 当你想要阻塞等待关闭信号时
death.WaitForDeathWithFunc(func(){
// 在关闭时做任何你想做的事情
})
}
发布流程
发布分支规则:
- 如果你要发布一个新的主版本,你需要从master分支创建一个名为
release-branch.v#
的分支(例如release-branch.v2
表示2.x版本) - 如果你要发布现有主版本的次要或补丁更新,请确保将master合并到发布分支中
标记和发布版本的规则
当你准备好发布版本时,请确保你…
- 将你的更改合并到正确的发布分支
- 在本地检出发布分支(例如:
git pull origin release-branch.v3
) - 为你将要发布的特定版本创建一个新标签(例如:
git tag v3.0.1
) - 将标签推送到github(例如:
git push origin v3.0.1
) - 转到github中的发布标签页
- 选择目标分支作为发布分支并输入标签名称(标签名称应包括
v
,例如:v3.0.1
) - 写一个标题和详细描述说明这个变更的具体内容
- 点击发布版本
更多关于golang优雅管理应用关闭信号的插件库Death的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang优雅管理应用关闭信号的插件库Death的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang优雅管理应用关闭信号的插件库Death使用指南
Death是一个轻量级的Go库,用于优雅地管理应用程序的关闭信号。它可以帮助你在程序收到终止信号时,优雅地关闭所有goroutine和资源。
安装Death库
go get github.com/vrecan/death/v3
基本使用示例
package main
import (
"context"
"fmt"
"time"
"github.com/vrecan/death/v3"
)
func main() {
// 创建Death实例
d := death.NewDeath()
// 模拟一个需要优雅关闭的服务
go func() {
for {
select {
case <-d.Dying():
fmt.Println("服务正在关闭...")
return
default:
fmt.Println("服务运行中...")
time.Sleep(1 * time.Second)
}
}
}()
// 等待系统信号并优雅关闭
d.WaitForDeath()
fmt.Println("应用程序已优雅关闭")
}
高级功能
1. 自定义关闭信号
func main() {
d := death.NewDeath(
death.Signals(syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT),
)
go func() {
<-d.Dying()
fmt.Println("收到关闭信号,开始清理...")
// 执行清理操作
}()
d.WaitForDeath()
}
2. 注册关闭回调函数
func main() {
d := death.NewDeath()
// 注册关闭时的回调函数
d.RegisterBeforeDeath(func() {
fmt.Println("执行关闭前的清理工作")
time.Sleep(2 * time.Second) // 模拟清理耗时
})
go func() {
for {
select {
case <-d.Dying():
fmt.Println("服务正在关闭...")
return
default:
fmt.Println("服务运行中...")
time.Sleep(1 * time.Second)
}
}
}()
d.WaitForDeath()
}
3. 结合context使用
func main() {
d := death.NewDeath()
ctx := context.Background()
// 创建一个可以感知Death的context
ctx, cancel := context.WithCancel(ctx)
defer cancel()
go func() {
<-d.Dying()
fmt.Println("收到关闭信号,取消context")
cancel()
}()
go func() {
for {
select {
case <-ctx.Done():
fmt.Println("context被取消,停止服务")
return
default:
fmt.Println("服务运行中...")
time.Sleep(1 * time.Second)
}
}
}()
d.WaitForDeath()
}
实际应用示例
package main
import (
"fmt"
"net/http"
"sync"
"time"
"github.com/vrecan/death/v3"
)
type Server struct {
httpServer *http.Server
wg sync.WaitGroup
}
func NewServer() *Server {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, World!"))
})
return &Server{
httpServer: &http.Server{
Addr: ":8080",
Handler: mux,
},
}
}
func (s *Server) Start() {
s.wg.Add(1)
go func() {
defer s.wg.Done()
fmt.Println("HTTP服务器启动")
if err := s.httpServer.ListenAndServe(); err != http.ErrServerClosed {
fmt.Printf("HTTP服务器错误: %v\n", err)
}
}()
}
func (s *Server) Stop() error {
fmt.Println("停止HTTP服务器...")
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
return s.httpServer.Shutdown(ctx)
}
func main() {
server := NewServer()
server.Start()
d := death.NewDeath()
// 注册关闭时的回调
d.RegisterBeforeDeath(func() {
fmt.Println("开始优雅关闭...")
if err := server.Stop(); err != nil {
fmt.Printf("关闭服务器时出错: %v\n", err)
}
server.wg.Wait() // 等待所有goroutine完成
})
fmt.Println("应用程序运行中,按Ctrl+C停止...")
d.WaitForDeath()
fmt.Println("应用程序已完全关闭")
}
最佳实践
-
资源清理:确保所有打开的文件、数据库连接、网络连接等在关闭时都被正确释放
-
超时控制:为关闭操作设置合理的超时时间,避免无限等待
-
并发安全:确保关闭操作是并发安全的
-
日志记录:记录关闭过程中的关键步骤,便于问题排查
-
分级关闭:按照依赖关系有序关闭服务,例如先关闭接收新请求,再处理已有请求,最后关闭资源
Death库提供了一种简单而强大的方式来管理Go应用程序的生命周期,特别是在需要优雅关闭的场景下非常有用。