Files
goproxy/internal/server/graceful.go
DarkiT 7efc72b362 增加:
1.  监控指标收集
2.  中间件机制
3.  配置热更新
4.  优雅关闭
5.  插件系统
6.  API文档
7.  认证授权系统
8.  请求/响应压缩优化
2025-03-13 22:58:39 +08:00

88 lines
1.7 KiB
Go

package server
import (
"context"
"log/slog"
"net/http"
"os"
"os/signal"
"sync"
"syscall"
"time"
)
// GracefulServer 优雅关闭服务器
type GracefulServer struct {
// HTTP服务器
server *http.Server
// 等待组
wg sync.WaitGroup
// 停止信号
stopChan chan struct{}
}
// NewGracefulServer 创建优雅关闭服务器
func NewGracefulServer(addr string, handler http.Handler) *GracefulServer {
return &GracefulServer{
server: &http.Server{
Addr: addr,
Handler: handler,
},
stopChan: make(chan struct{}),
}
}
// Start 启动服务器
func (s *GracefulServer) Start() error {
// 启动HTTP服务器
go func() {
slog.Info("启动HTTP服务器", "addr", s.server.Addr)
if err := s.server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
slog.Error("HTTP服务器错误", "error", err)
}
}()
// 等待中断信号
s.waitForInterrupt()
return nil
}
// waitForInterrupt 等待中断信号
func (s *GracefulServer) waitForInterrupt() {
// 创建信号通道
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
// 等待信号
<-sigChan
slog.Info("收到停止信号,开始优雅关闭")
// 创建关闭上下文
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
// 关闭HTTP服务器
if err := s.server.Shutdown(ctx); err != nil {
slog.Error("关闭HTTP服务器失败", "error", err)
}
// 通知所有goroutine停止
close(s.stopChan)
// 等待所有goroutine结束
s.wg.Wait()
slog.Info("服务器已优雅关闭")
}
// Stop 停止服务器
func (s *GracefulServer) Stop() {
close(s.stopChan)
}
// WaitGroup 获取等待组
func (s *GracefulServer) WaitGroup() *sync.WaitGroup {
return &s.wg
}