package redisdo import ( "errors" "leafstalk/covenant/monitor" "strconv" "time" "github.com/gomodule/redigo/redis" ) var ( pool *redis.Pool ) func newRedisPool(addr string, password string, db int) *redis.Pool { // addr := config.GetString("redis.addr") // password := config.GetString("redis.auth") // db := config.GetInt("redis.db") return &redis.Pool{ MaxIdle: 10, IdleTimeout: 240 * time.Second, // Dial or DialContext must be set. When both are set, DialContext takes precedence over Dial. Dial: func() (redis.Conn, error) { c, err := redis.Dial("tcp", addr) if err != nil { return nil, err } if len(password) != 0 { if _, err := c.Do("AUTH", password); err != nil { c.Close() return nil, err } } if _, err := c.Do("SELECT", db); err != nil { c.Close() return nil, err } return c, nil }, TestOnBorrow: func(c redis.Conn, t time.Time) error { if time.Since(t) < time.Minute { return nil } _, err := c.Do("PING") return err }, } } func InitRedisPool(addr string, password string, db int) { pool = newRedisPool(addr, password, db) } // CloseRedisPool 关闭reids池 func CloseRedisPool() { if pool != nil { pool.Close() } } func Do(commandName string, args ...interface{}) (reply interface{}, err error) { defer monitor.RedisDoTimeoutWarn("Do", map[string]interface{}{ "commandName": commandName, "args": args, }, time.Now()) conn := pool.Get() defer conn.Close() return conn.Do(commandName, args...) } func DoMulti(f func(conn redis.Conn) error) error { defer monitor.RedisDoTimeoutWarn("DoMulti", "", time.Now()) conn := pool.Get() defer conn.Close() return f(conn) //return conn.Do(commandName, args...) } // 保存一个集合 func DoFlat(commandName string, key string, val interface{}) (reply interface{}, err error) { conn := pool.Get() defer conn.Close() //组织为串 return conn.Do(commandName, redis.Args{key}.AddFlat(val)...) } func IsNilError(err error) bool { return err == redis.ErrNil } func DoHashSet(key string, val interface{}) (reply interface{}, err error) { conn := pool.Get() defer conn.Close() //以hash类型保存 return conn.Do("hmset", redis.Args{key}.AddFlat(val)...) } // 是否发现,是否出错 func DoHashGet(key string, strc interface{}) (bool, error) { conn := pool.Get() defer conn.Close() //获取缓存 value, err := redis.Values(conn.Do("hgetall", key)) if err != nil { return false, err } if len(value) == 0 { return false, nil } //将values转成结构体 err = redis.ScanStruct(value, strc) if err != nil { return true, err } return true, nil } // 模糊匹配搜索 func ScanKeys(start int, pattern string, count int) (int, []string, error) { rep, err := Do("scan", start, "match", pattern, "count", count) if err != nil { return 0, nil, err } rep2 := rep.([]interface{}) if len(rep2) != 2 { return 0, nil, errors.New("replay length is error") } nextSt := "" if strSt, ok := rep2[0].([]byte); !ok { return 0, nil, errors.New("replay type is error") } else { nextSt = string(strSt) } var lst []string if ks, ok := rep2[1].([]interface{}); !ok { return 0, nil, errors.New("replay type is error") } else { for _, v := range ks { if nv, ok := v.([]byte); ok { k := string(nv) lst = append(lst, k) } } } st, err := strconv.Atoi(nextSt) if err != nil { return 0, lst, nil } return st, lst, nil } func HScanKeys(key string, start int, pattern string, count int) (int, map[string]string, error) { rep, err := redis.Values(Do("hscan", key, start, "match", pattern, "count", count)) if err != nil { return 0, nil, err } next, err := redis.Int(rep[0], err) if err != nil { return 0, nil, err } lst, err := redis.StringMap(rep[1], err) if err != nil { return 0, nil, err } return next, lst, nil } func test() { //onlinestate.Do("SET", "foo", "bar") // currentTimeStart := time.Now() // onlinestate.DoMulti(func(conn redis.Conn) error { // for i := 0; i < 100000; i++ { // conn.Do("INCR", "TESTKEY") // } // return err // }) // fmt.Println(time.Since(currentTimeStart)) // currentTimeStart = time.Now() // onlinestate.DoMulti(func(conn redis.Conn) error { // for i := 0; i < 100000; i++ { // conn.Send("INCR", "TESTKEY") // } // conn.Flush() // conn.Receive() // return err // }) // fmt.Println(time.Since(currentTimeStart)) // currentTimeStart = time.Now() // onlinestate.DoMulti(func(conn redis.Conn) error { // for i := 0; i < 100000; i++ { // conn.Send("INCR", "TESTKEY") // conn.Flush() // } // conn.Receive() // return err // }) // fmt.Println(time.Since(currentTimeStart)) }