1. ✅ 监控指标收集 2. ✅ 中间件机制 3. ✅ 配置热更新 4. ✅ 优雅关闭 5. ✅ 插件系统 6. ✅ API文档 7. ✅ 认证授权系统 8. ✅ 请求/响应压缩优化
88 lines
1.7 KiB
Go
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
|
|
}
|