package redis import ( "time" "git.shuncheng.lu/bigthing/gocommon/pkg/internal/util" "github.com/garyburd/redigo/redis" ) // 先不支持tls type Config struct { Host string `json:"host"` Password string `json:"password"` // 默认没有 Database int `json:"database"` // 默认0 IdleTimeout time.Duration `json:"idle_timeout"` // 空闲的超时时间,默认10s MaxIdle int `json:"max_idle"` // 默认50 MaxActive int `json:"max_conn"` // 默认10000 ConnectTimeOut time.Duration `json:"connect_time_out"` // 默认超时都是5s ReadTimeOut time.Duration `json:"read_time_out"` WriteTimeOut time.Duration `json:"write_time_out"` } func getRedisConfigFromMap(config map[string]string) Config { return Config{ Host: config["host"], Password: config["password"], Database: util.String2Int(config["database"]), IdleTimeout: util.StringSecToDuration(config["idle_timeout"]), MaxIdle: util.String2Int(config["max_idle"]), MaxActive: util.String2Int(config["max_conn"]), ConnectTimeOut: util.StringSecToDuration(config["connect_time_out"]), ReadTimeOut: util.StringSecToDuration(config["read_time_out"]), WriteTimeOut: util.StringSecToDuration(config["write_time_out"]), } } func getRedisConfig(key string, assertNil util.SetAndAssertNil) (map[string]string, error) { config := make(map[string]string, 0) if err := assertNil(config, key, "host", ""); err != nil { return nil, err } if err := assertNil(config, key, "cache_prefix", ""); err != nil { //return nil, err util.Warnf("%s config not set cache_prefix default nil ", key) } if err := assertNil(config, key, "password", ""); err != nil { //return nil, err util.Warnf("%s config not set password default nil ", key) } if err := assertNil(config, key, "database", ""); err != nil { //return nil, err util.Warnf("%s config not set database default 0", key) } if err := assertNil(config, key, "idle_timeout", "10"); err != nil { return nil, err } if err := assertNil(config, key, "max_idle", "50"); err != nil { return nil, err } if err := assertNil(config, key, "max_conn", "10000"); err != nil { return nil, err } if err := assertNil(config, key, "connect_time_out", "5"); err != nil { return nil, err } if err := assertNil(config, key, "read_time_out", "5"); err != nil { return nil, err } if err := assertNil(config, key, "write_time_out", "5"); err != nil { return nil, err } if err := assertNil(config, key, "is_direct", "false"); err != nil { return nil, err } return config, nil } func newRedisPool(config Config) (*redis.Pool, error) { ping := func(r *redis.Pool) error { cnn := r.Get() defer cnn.Close() _, err := cnn.Do("PING") return err } init := func(config Config) Config { if config.ReadTimeOut == 0 { config.ReadTimeOut = time.Second * 5 } if config.ConnectTimeOut == 0 { config.ConnectTimeOut = time.Second * 5 } if config.WriteTimeOut == 0 { config.WriteTimeOut = time.Second * 5 } if config.MaxActive == 0 { config.MaxActive = 10000 } if config.MaxIdle == 0 { config.MaxIdle = 10 } if config.IdleTimeout == 0 { config.IdleTimeout = time.Second * 10 } return config } config = init(config) pool := &redis.Pool{ //Wait: true, // 是否等待从连接池中获取,这里最好设置为false,默认就是false MaxActive: config.MaxActive, MaxIdle: config.MaxIdle, IdleTimeout: config.IdleTimeout, Dial: func() (redis.Conn, error) { c, err := redis.Dial("tcp", config.Host, redis.DialConnectTimeout(config.ConnectTimeOut), redis.DialReadTimeout(config.ReadTimeOut), redis.DialWriteTimeout(config.WriteTimeOut), redis.DialPassword(config.Password), redis.DialDatabase(config.Database), ) if err != nil { return nil, err } return c, err }, TestOnBorrow: func(c redis.Conn, t time.Time) error { // 如果小于空闲时间,则不进行检测,优化好处不用每次拿去连接都ping一次(t是上次使用的时间) //fmt.Printf("pre: %s, cur: %s, idel: %v\n", t.Format("2006-01-02 15:04:05"), time.Now().Format("2006-01-02 15:04:05"), config.IdleTimeout/time.Second) if time.Since(t) < config.IdleTimeout { return nil } //fmt.Println("ping") _, err := c.Do("PING") //defer c.Close() // 这里不能关闭,当去借连接的时候,回去测试一下连接是否可用 return err }, } if err := ping(pool); err != nil { pool.Close() return nil, err } return pool, nil }