package boot import ( "fmt" "net/http" "os" "os/signal" "syscall" "time" "github.com/gin-gonic/gin" "github.com/gomodule/redigo/redis" "github.com/spf13/viper" "go.uber.org/zap" "passport/app/router" "passport/app/rpc" "passport/client/mysql" "passport/client/sredis" "passport/logger" ) const ( // gracefulTimeout controls how long we wait before forcefully terminating gracefulTimeout = 3 * time.Second ) func Run() int { var err error StoreInit() err = InitModel() if err != nil { panic(err) } go StartHttpServer() go rpc.StartGrpcServer() return handleSignals() } //初始化相关必要持久化服务 func StoreInit() { //连接mysql var err error // 连接数据库 _, err = mysql.Dial("mysql", viper.GetString("mysql.address")) if err != nil { panic(err) } //初始化redis sredis.MasterPool = &redis.Pool{ //实例化一个连接池 MaxIdle: 16, //最初的连接数量 // MaxActive:1000000, //最大连接数量 MaxActive: 0, //连接池最大连接数量,不确定可以用0(0表示自动定义),按需分配 IdleTimeout: 300, //连接关闭时间 300秒 (300秒不使用自动关闭) Dial: func() (redis.Conn, error) { //要连接的redis数据库 conn, err := redis.Dial("tcp", viper.GetString("redis.master.address")) if err != nil { return nil, err } if viper.GetString("redis.master.password") != "" { _, err = conn.Do("AUTH", viper.GetString("redis.master.password")) if err != nil { return nil, err } } return conn, err }, } sredis.SalvePool = &redis.Pool{ //实例化一个连接池 MaxIdle: 16, //最初的连接数量 // MaxActive:1000000, //最大连接数量 MaxActive: 0, //连接池最大连接数量,不确定可以用0(0表示自动定义),按需分配 IdleTimeout: 300, //连接关闭时间 300秒 (300秒不使用自动关闭) Dial: func() (redis.Conn, error) { //要连接的redis数据库 conn, err := redis.Dial("tcp", viper.GetString("redis.slave.address")) if err != nil { return nil, err } if viper.GetString("redis.slave.password") != "" { _, err = conn.Do("AUTH", viper.GetString("redis.slave.password")) if err != nil { return nil, err } } return conn, err }, } } //启动服务 func StartHttpServer() { // r := gin.Default() router.StepRouters(r) addr := fmt.Sprintf("%s:%d", viper.GetString("server.host"), viper.GetInt("server.port")) logger.Info(fmt.Sprintf("Http Server has been started. http://%s", addr)) logger.Fatal("start http server", zap.Error(http.ListenAndServe(addr, r))) } func handleSignals() int { signalCh := make(chan os.Signal, 4) signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP) WAIT: // Wait for a signal var sig os.Signal select { case s := <-signalCh: sig = s } //log.Info(fmt.Sprintf("Caught signal: %v", sig)) // Check if this is a SIGHUP if sig == syscall.SIGHUP { //重新加载配置 goto WAIT } // Check if we should do a graceful leave graceful := false if sig == syscall.SIGTERM || sig == os.Interrupt { graceful = true } // Fail fast if not doing a graceful leave if !graceful { return 1 } // Attempt a graceful leave gracefulCh := make(chan struct{}) //log.Info("Gracefully shutting down...") go func() { //if err := c.Sys.Leave(); err != nil { // log.Error(fmt.Sprintf("Error: %s", err)) // return //} close(gracefulCh) }() // Wait for leave or another signal select { case <-signalCh: return 1 case <-time.After(gracefulTimeout): return 1 case <-gracefulCh: return 0 } }