server_run.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. package core
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. "os"
  7. "os/signal"
  8. "syscall"
  9. "time"
  10. "github.com/gin-gonic/gin"
  11. "go.uber.org/zap"
  12. )
  13. type server interface {
  14. ListenAndServe() error
  15. Shutdown(context.Context) error
  16. }
  17. // initServer 启动服务并实现优雅关闭
  18. func initServer(address string, router *gin.Engine, readTimeout, writeTimeout time.Duration) {
  19. // 创建服务
  20. srv := &http.Server{
  21. Addr: address,
  22. Handler: router,
  23. ReadTimeout: readTimeout,
  24. WriteTimeout: writeTimeout,
  25. MaxHeaderBytes: 1 << 20,
  26. }
  27. // 在goroutine中启动服务
  28. go func() {
  29. if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
  30. fmt.Printf("listen: %s\n", err)
  31. zap.L().Error("server启动失败", zap.Error(err))
  32. os.Exit(1)
  33. }
  34. }()
  35. // 等待中断信号以优雅地关闭服务器
  36. quit := make(chan os.Signal, 1)
  37. // kill (无参数) 默认发送 syscall.SIGTERM
  38. // kill -2 发送 syscall.SIGINT
  39. // kill -9 发送 syscall.SIGKILL,但是无法被捕获,所以不需要添加
  40. signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
  41. <-quit
  42. zap.L().Info("关闭WEB服务...")
  43. // 设置5秒的超时时间
  44. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  45. defer cancel()
  46. if err := srv.Shutdown(ctx); err != nil {
  47. zap.L().Fatal("WEB服务关闭异常", zap.Error(err))
  48. }
  49. zap.L().Info("WEB服务已关闭")
  50. }