package sysmodule import ( "bytes" "encoding/json" "errors" "fmt" "github.com/duanhf2012/origin/log" "time" "github.com/duanhf2012/origin/service" "github.com/gomodule/redigo/redis" ) //最大redis信道任务量 const ( MAX_TASK_CHANNEL = 10240 ) type RetError struct { resultChan chan error } func (slf *RetError) Get() error { return <-slf.resultChan } type ErrorMapStringBool struct { resultError error resultMapStringBool map[string]bool } type RetMapString struct { resultChan chan ErrorMapStringBool } func (slf *RetMapString) Get() (error, map[string]bool) { ret := <-slf.resultChan return ret.resultError, ret.resultMapStringBool } type Func func() type RedisModule struct { service.Module redispool *redis.Pool redisTask chan Func } // ConfigRedis 服务器配置 type ConfigRedis struct { IP string Port string Password string DbIndex int MaxIdle int //最大的空闲连接数,表示即使没有redis连接时依然可以保持N个空闲的连接,而不被清除,随时处于待命状态。 MaxActive int //最大的激活连接数,表示同时最多有N个连接 IdleTimeout int //最大的空闲连接等待时间,超过此时间后,空闲连接将被关闭 SyncRouterNum int //异步执行Router数量 } func (slf *RedisModule) Init(redisCfg *ConfigRedis) { redisServer := redisCfg.IP + ":" + redisCfg.Port slf.redispool = &redis.Pool{ Wait: true, MaxIdle: redisCfg.MaxIdle, MaxActive: redisCfg.MaxActive, IdleTimeout: time.Duration(redisCfg.IdleTimeout) * time.Second, Dial: func() (redis.Conn, error) { // 连接数据库 opt := []redis.DialOption{redis.DialDatabase(redisCfg.DbIndex)} if redisCfg.Password != "" { opt = append(opt, redis.DialPassword(redisCfg.Password)) } c, err := redis.Dial("tcp", redisServer, opt...) if err != nil { log.Error("Connect redis fail reason:%v", err) return nil, err } return c, err }, TestOnBorrow: func(c redis.Conn, t time.Time) error { if time.Since(t) < time.Minute { return nil } _, err := c.Do("PING") if err != nil { log.Error("Do PING fail reason:%v", err) return err } return err }, } slf.redisTask = make(chan Func, MAX_TASK_CHANNEL) for i := 0; i < redisCfg.SyncRouterNum; i++ { go slf.RunAnsyTask() } } func (slf *RedisModule) RunAnsyTask() { for { task := <-slf.redisTask task() } } func (slf *RedisModule) GoTask(fc Func) error { if len(slf.redisTask) >= MAX_TASK_CHANNEL { log.Error("Redis task channel recover max.") return fmt.Errorf("Redis task channel recover max.") } slf.redisTask <- fc return nil } // GetConn ... func (slf *RedisModule) getConn() (redis.Conn, error) { if slf.redispool == nil { log.Error("Not Init RedisModule") return nil, fmt.Errorf("Not Init RedisModule") } conn := slf.redispool.Get() if conn == nil { log.Error("Cannot get connection") return nil, fmt.Errorf("Cannot get connection") } if conn.Err() != nil { err := conn.Err() if err != nil { log.Error("Get Conn have error,reason:%v", err) } conn.Close() return nil, err } return conn, nil } //TestPingRedis 测试连接Redis func (slf *RedisModule) TestPingRedis() error { conn, err := slf.getConn() if err != nil { return err } defer conn.Close() err = slf.redispool.TestOnBorrow(conn, time.Now()) if err != nil { log.Error("TestOnBorrow fail,reason:%v", err) return err } return nil } //SetRedisString redis添加string类型数据 无过期时间 //示例:SetRedisString("TestKey", "Hell World!") func (slf *RedisModule) SetString(key, value string) (err error) { err = slf.setStringByExpire(key, value, "-1") return err } func (slf *RedisModule) GoSetString(key, value string, err *RetError) { slf.GoSetStringExpire(key, value, "-1", err) } //SetRedisExString redis添加string类型数据 有过期时间 ex过期时间,单位秒,必须是整数 //示例:SetRedisExString("TestKey", "Hell World!","60") func (slf *RedisModule) SetStringExpire(key, value, expire string) (err error) { err = slf.setStringByExpire(key, value, expire) return err } func (slf *RedisModule) GoSetStringExpire(key, value string, expire string, err *RetError) error { if err != nil { err.resultChan = make(chan error, 1) } fun := func() { if err != nil { ret := slf.setStringByExpire(key, value, expire) err.resultChan <- ret } else { slf.setStringByExpire(key, value, expire) } } slf.GoTask(fun) return nil } //SetRedisStringJSON redis添加JSON数据 无过期时间 //示例:SetRedisStringJSON("AAAABTEST1", eagleconfig.Cfg) func (slf *RedisModule) SetStringJSON(key string, val interface{}) (err error) { err = slf.SetStringJSONExpire(key, val, "-1") return err } func (slf *RedisModule) GoSetStringJSON(key string, val interface{}, err *RetError) { slf.GoSetStringJSONExpire(key, val, "-1", err) } //SetRedisExStringJSON redis添加JSON数据 有过期时间 ex过期时间,单位秒,必须是整数 //示例:SetRedisStringJSON("AAAABTEST1", eagleconfig.Cfg,"60") func (slf *RedisModule) SetStringJSONExpire(key string, val interface{}, expire string) (err error) { if temp, err := json.Marshal(val); err == nil { err = slf.setStringByExpire(key, string(temp), expire) } return err } func (slf *RedisModule) GoSetStringJSONExpire(key string, val interface{}, expire string, retErr *RetError) error { temp, err := json.Marshal(val) if err == nil { slf.GoSetStringExpire(key, string(temp), expire, retErr) return nil } else { log.Error("GoSetStringJSONExpire fail,reason:%v", err) retErr.resultChan <- err } return err } func (slf *RedisModule) setStringByExpire(key, value, expire string) error { if key == "" { return errors.New("Key Is Empty") } conn, err := slf.getConn() if err != nil { return err } defer conn.Close() var ret interface{} var retErr error if expire == "-1" { ret, retErr = conn.Do("SET", key, value) } else { ret, retErr = conn.Do("SET", key, value, "EX", expire) } if retErr != nil { log.Error("setStringByExpire fail,reason:%v", retErr) return retErr } _, ok := ret.(string) if !ok { retErr = errors.New("setStringByExpire redis data is error") log.Error("setStringByExpire redis data is error") return retErr } return nil } //SetMuchRedisString redis添加多条string类型数据 //示例:SetMuchRedisString(map[string]string{"Test1": "C语言", "Test2": "Go语言", "Test3": "Python", "Test4": "C++"}) func (slf *RedisModule) SetMuchString(mapInfo map[string]string) (err error) { err = slf.setMuchStringByExpire(mapInfo, "-1") return } func (slf *RedisModule) GoSetMuchString(mapInfo map[string]string, retErr *RetError) { slf.GoSetMuchStringExpire(mapInfo, "-1", retErr) } //SetMuchRedisStringSameEx redis添加多条string类型数据 具有相同的过期时间 ex过期时间 整数 //示例:SetMuchRedisStringSameEx(map[string]string{"Test1": "C语言", "Test2": "Go语言", "Test3": "Python", "Test4": "C++"},"300") func (slf *RedisModule) SetMuchStringExpire(mapInfo map[string]string, ex string) (err error) { err = slf.setMuchStringByExpire(mapInfo, ex) return } func (slf *RedisModule) GoSetMuchStringExpire(mapInfo map[string]string, expire string, err *RetError) { if err != nil { err.resultChan = make(chan error, 1) } fun := func() { if err != nil { ret := slf.setMuchStringByExpire(mapInfo, expire) err.resultChan <- ret } else { slf.setMuchStringByExpire(mapInfo, expire) } } slf.GoTask(fun) } func (slf *RedisModule) setMuchStringByExpire(mapInfo map[string]string, expire string) error { if len(mapInfo) <= 0 { log.Error("setMuchStringByExpire Info Is Empty") return errors.New("setMuchStringByExpire Info Is Empty") } conn, err := slf.getConn() if err != nil { return err } defer conn.Close() // 开始Send数据 conn.Send("MULTI") for key, val := range mapInfo { if expire == "-1" { conn.Send("SET", key, val) } else { conn.Send("SET", key, val, "EX", expire) } } // 执行命令 _, err = conn.Do("EXEC") if err != nil { log.Error("setMuchStringByExpire fail,reason:%v", err) } return err } //GetRedisString redis获取string类型数据 //示例:GetRedisString("TestKey") func (slf *RedisModule) GetString(key string) (string, error) { conn, err := slf.getConn() if err != nil { return "", err } defer conn.Close() ret, err := conn.Do("GET", key) if err != nil { log.Error("GetString fail,reason:%v", err) return "", err } if ret == nil { err = errors.New("GetString key is not exist!") return "", err } str, ok := ret.([]byte) if !ok { err = errors.New("GetString redis data is error") log.Error("GetString redis data is error") return "", err } return string(str), nil } //GetRedisStringJSON redis获取string类型数据的Json //示例:GetRedisString("TestKey") func (slf *RedisModule) GetStringJSON(key string, st interface{}) error { conn, err := slf.getConn() if err != nil { return err } defer conn.Close() ret, err := conn.Do("GET", key) if err != nil { log.Error("GetStringJSON fail,reason:%v", err) return err } if ret == nil { err = errors.New("GetStringJSON Key is not exist") return err } str, ok := ret.([]byte) if !ok { err = errors.New("GetStringJSON redis data is error!") log.Error("GetStringJSON redis data is error!") return err } if err = json.Unmarshal(str, st); err != nil { log.Error("GetStringJSON fail json.Unmarshal is error:%s,%s,reason:%v", key, string(str), err) return err } return nil } //GetMuchRedisString redis获取string类型数据 //Pipeline实现的原理是队列,而队列的原理是先进先出 //示例:GetMuchRedisString(&[]string{"AAAABTEST1", "AAAABTEST2"}) func (slf *RedisModule) GetMuchString(keys []string) (retMap map[string]string, err error) { if len(keys) <= 0 { err = errors.New("Func[GetMuchRedisString] Keys Is Empty") return } conn, err := slf.getConn() if err != nil { return nil, err } defer conn.Close() // 开始Send数据 err = conn.Send("MULTI") if err != nil { log.Error("GetMuchString fail %v", err) return nil, err } for _, val := range keys { conn.Send("GET", val) } // 执行命令 ret, err := conn.Do("EXEC") if err != nil { log.Error("GetMuchString fail %v", err) return } retList, ok := ret.([]interface{}) if !ok { err = errors.New("Func[GetMuchRedisString] Redis Data Error") return } retMap = make(map[string]string) for index, val := range retList { strVal, ok := val.([]byte) if !ok { retMap[keys[index]] = "" continue } retMap[keys[index]] = string(strVal) } err = nil return } //GetMuchRedisStringJSON redis获取string类型数据Json //Pipeline实现的原理是队列,而队列的原理是先进先出 //示例:temp := make(map[string]interface{}) //temp["AAAABTEST1"] = &eagleconfig.ServerConfig{} //temp["AAAABTEST2"] = &eagleconfig.ServerConfig{} //GetMuchRedisStringJSON(&temp) func (slf *RedisModule) GetMuchStringJSON(keys map[string]interface{}) error { if len(keys) <= 0 { err := errors.New("GetMuchStringJSON fail key is empty") log.Error("GetMuchStringJSON fail key is empty") return err } conn, err := slf.getConn() if err != nil { return err } defer conn.Close() // 开始Send数据 conn.Send("MULTI") var tempKeys []string for key := range keys { tempKeys = append(tempKeys, key) conn.Send("GET", key) } // 执行命令 ret, err := conn.Do("EXEC") if err != nil { log.Error("GetMuchStringJSON fail, reason:%v", err) return err } retList, ok := ret.([]interface{}) if !ok { err = errors.New("Func[GetMuchRedisStringJSON] Redis Data Error") return err } fmt.Println(tempKeys) for index, val := range retList { strVal, ok := val.([]byte) if !ok { continue } err = json.Unmarshal(strVal, keys[tempKeys[index]]) if err != nil { log.Error("GetMuchStringJSON Unmarshal fail, reason:%v", err) return err } } return nil } //判断一个Key是否存在 func (slf *RedisModule) ExistsKey(key string) (bool, error) { conn, err := slf.getConn() if err != nil { return false, err } defer conn.Close() ret, err := conn.Do("EXISTS", key) if err != nil { log.Error("ExistsKey fail, reason:%v", err) return false, err } retValue, ok := ret.(int64) if !ok { err = errors.New("Func[ExistsKey] Redis Data Error") return false, err } return retValue != 0, nil } //DelRedisString redis删除string类型数据 //示例:DelRedisString("AAAABTEST1") func (slf *RedisModule) DelString(key string) error { conn, err := slf.getConn() if err != nil { return err } defer conn.Close() ret, err := conn.Do("DEL", key) if err != nil { log.Error("DelString fail, reason:%v", err) return err } retValue, ok := ret.(int64) if !ok { err = errors.New("Func[DelRedisString] Redis Data Error") return err } if retValue == 0 { err = fmt.Errorf("Func[DelRedisString] Delete Key(%s) not exists", key) return err } return nil } func (slf *RedisModule) GoDelString(key string, err *RetError) { if err != nil { err.resultChan = make(chan error, 1) } fun := func() { if err != nil { ret := slf.DelString(key) err.resultChan <- ret } else { slf.DelString(key) } } slf.GoTask(fun) } func (slf *RedisModule) GoDelMuchString(keys []string, retMapString *RetMapString) { if retMapString != nil { retMapString.resultChan = make(chan ErrorMapStringBool, 1) } fun := func() { if retMapString != nil { var retchan ErrorMapStringBool retchan.resultMapStringBool, retchan.resultError = slf.DelMuchString(keys) retMapString.resultChan <- retchan } else { slf.DelMuchString(keys) } } slf.GoTask(fun) } //DelMuchRedisString redis删除string类型数据 //示例:DelMuchRedisString([]string{"AAAABTEST1",""AAAABTEST2}) func (slf *RedisModule) DelMuchString(keys []string) (map[string]bool, error) { if len(keys) <= 0 { err := errors.New("Func[DelMuchRedisString] Keys Is Empty") return nil, err } conn, err := slf.getConn() if err != nil { return nil, err } defer conn.Close() // 开始Send数据 conn.Send("MULTI") for _, val := range keys { conn.Send("DEL", val) } // 执行命令 ret, err := conn.Do("EXEC") if err != nil { log.Error("DelMuchString fail,reason:%v", err) return nil, err } retList, ok := ret.([]interface{}) if !ok { err = errors.New("Func[DelMuchRedisString] Redis Data Error") return nil, err } retMap := map[string]bool{} for index, val := range retList { iVal, ok := val.(int64) if !ok || iVal == 0 { retMap[keys[index]] = false continue } retMap[keys[index]] = true } return retMap, nil } //SetRedisHash ... //如果 hsahKey 是哈希表中的一个新建域,并且值设置成功,返回 1 //如果哈希表中域 hsahKey 已经存在且旧值已被新值覆盖,返回 0 func (slf *RedisModule) SetHash(redisKey, hashKey, value string) error { if redisKey == "" || hashKey == "" { return errors.New("Key Is Empty") } conn, err := slf.getConn() if err != nil { return err } defer conn.Close() _, retErr := conn.Do("HSET", redisKey, hashKey, value) if retErr != nil { log.Error("SetHash fail,reason:%v", retErr) } return retErr } func (slf *RedisModule) GoSetHash(redisKey, hashKey, value string, err *RetError) { if err != nil { err.resultChan = make(chan error, 1) } fun := func() { if err != nil { err.resultChan <- slf.SetHash(redisKey, hashKey, value) } else { slf.SetHash(redisKey, hashKey, value) } } slf.GoTask(fun) } //GetRedisAllHashJSON ... func (slf *RedisModule) GetAllHashJSON(redisKey string) (map[string]string, error) { if redisKey == "" { return nil, errors.New("Key Is Empty") } conn, err := slf.getConn() if err != nil { return nil, err } defer conn.Close() value, err := conn.Do("HGETALL", redisKey) if err != nil { log.Error("GetAllHashJSON fail,reason:%v", err) return nil, err } return redis.StringMap(value, err) } //GetRedisHashValueByKey ... func (slf *RedisModule) GetHashValueByKey(redisKey string, fieldKey string) (string, error) { if redisKey == "" || fieldKey == "" { log.Error("GetHashValueByKey key is empty!") return "", errors.New("Key Is Empty") } conn, err := slf.getConn() if err != nil { return "", err } defer conn.Close() value, err := conn.Do("HGET", redisKey, fieldKey) if err != nil { log.Error("GetHashValueByKey fail,reason:%v", err) return "", err } if value == nil { return "", errors.New("Reids Get Hash nil") } str, ok := value.([]byte) if !ok { err = errors.New("Func[GetRedisHashValueByKey] Redis Data Error") return "", err } return string(str), nil } //SetRedisHashJSON ... func (slf *RedisModule) SetHashJSON(redisKey, hsahKey string, value interface{}) error { temp, err := json.Marshal(value) if err == nil { err = slf.SetHash(redisKey, hsahKey, string(temp)) } return err } func (slf *RedisModule) GoSetHashJSON(redisKey, hsahKey string, value interface{}, err *RetError) { temp, retErr := json.Marshal(value) if retErr == nil { slf.GoSetHash(redisKey, hsahKey, string(temp), err) } else { if err != nil { err.resultChan = make(chan error, 1) err.resultChan <- retErr } } } //SetMuchRedisHashJSON ... value : hashkey -> value func (slf *RedisModule) SetMuchHashJSON(redisKey string, value map[string][]interface{}) error { if len(value) <= 0 { err := errors.New("Func[SetMuchRedisHashJSON] value Is Empty") return err } conn, err := slf.getConn() if err != nil { return err } defer conn.Close() // 开始Send数据 conn.Send("MULTI") for symbol, val := range value { temp, err := json.Marshal(val) if err == nil { conn.Do("HSET", redisKey, symbol, temp) } } // 执行命令 _, err = conn.Do("EXEC") if err != nil { log.Error("SetMuchHashJSON fail,reason:%v", err) } return err } func (slf *RedisModule) GoSetMuchHashJSON(redisKey string, value map[string][]interface{}, err *RetError) { if err != nil { err.resultChan = make(chan error, 1) } fun := func() { if err != nil { err.resultChan <- slf.SetMuchHashJSON(redisKey, value) } else { slf.SetMuchHashJSON(redisKey, value) } } slf.GoTask(fun) } //GoDelRedisHash func (slf *RedisModule) GoDelHash(redisKey string, hsahKey string, err *RetError) { tempHashKey := []string{hsahKey} slf.GoDelMuchHash(redisKey, tempHashKey, err) } //DelRedisHash ... func (slf *RedisModule) DelHash(redisKey string, hsahKey string) error { tempHashKey := []string{hsahKey} err := slf.DelMuchHash(redisKey, tempHashKey) return err } //GoDelMuchRedisHash func (slf *RedisModule) GoDelMuchHash(redisKey string, hsahKey []string, err *RetError) { if err != nil { err.resultChan = make(chan error, 1) } fun := func() { if err != nil { err.resultChan <- slf.DelMuchHash(redisKey, hsahKey) } else { slf.DelMuchHash(redisKey, hsahKey) } } slf.GoTask(fun) } //DelMuchRedisHash ... func (slf *RedisModule) DelMuchHash(redisKey string, hsahKey []string) error { if redisKey == "" || len(hsahKey) <= 0 { return errors.New("Key Is Empty") } conn, err := slf.getConn() if err != nil { return err } defer conn.Close() arg := []interface{}{redisKey} for _, k := range hsahKey { arg = append(arg, k) } _, retErr := conn.Do("HDEL", arg...) if retErr != nil { log.Error("DelMuchHash fail,reason:%v", retErr) } return retErr } //gosetRedisList func (slf *RedisModule) gosetList(key string, value []string, setType string, err *RetError) { if err != nil { err.resultChan = make(chan error, 1) } fun := func() { if err != nil { err.resultChan <- slf.setList(key, value, setType) } else { slf.setList(key, value, setType) } } slf.GoTask(fun) } //LPUSH和RPUSH func (slf *RedisModule) setList(key string, value []string, setType string) error { if key == "" { return errors.New("Key Is Empty") } if setType != "LPUSH" && setType != "RPUSH" { return errors.New("Redis List Push Type Error,Must Be LPUSH or RPUSH") } conn, err := slf.getConn() if err != nil { return err } defer conn.Close() arg := []interface{}{key} for _, k := range value { arg = append(arg, k) } _, retErr := conn.Do(setType, arg...) if retErr != nil { log.Error("setList fail,reason:%v", retErr) } return retErr } //SetRedisListLpush ... func (slf *RedisModule) SetListLpush(key, value string) error { tempVal := []string{value} err := slf.setList(key, tempVal, "LPUSH") return err } //GoSetRedisListLpush... func (slf *RedisModule) GoSetListLpush(key, value string, err *RetError) { tempVal := []string{value} slf.gosetList(key, tempVal, "LPUSH", err) } //SetMuchRedisListLpush ... func (slf *RedisModule) SetMuchListLpush(key string, value []string) error { return slf.setList(key, value, "LPUSH") } //GoSetMuchListLpush ... func (slf *RedisModule) GoSetMuchListLpush(key string, value []string, err *RetError) { slf.gosetList(key, value, "LPUSH", err) } //SetRedisListJSONLpush ... func (slf *RedisModule) SetListJSONLpush(key string, value interface{}) error { temp, err := json.Marshal(value) if err == nil { tempVal := []string{string(temp)} err = slf.setList(key, tempVal, "LPUSH") } else { log.Error("SetListJSONLpush fail,reason:%v", err) } return err } //GoSetRedisListJSONLpush ... func (slf *RedisModule) GoSetListJSONLpush(key string, value interface{}, retErr *RetError) { temp, err := json.Marshal(value) if err == nil { tempVal := []string{string(temp)} slf.gosetList(key, tempVal, "LPUSH", retErr) } else { if err != nil { retErr.resultChan = make(chan error, 1) retErr.resultChan <- err } } } //GoSetMuchListJSONLpush ... func (slf *RedisModule) GoSetMuchListJSONLpush(key string, value []interface{}, retErr *RetError) { tempVal := []string{} for _, val := range value { if temp, err := json.Marshal(val); err == nil { tempVal = append(tempVal, string(temp)) } } slf.gosetList(key, tempVal, "LPUSH", retErr) } //SetMuchListJSONLpush ... func (slf *RedisModule) SetMuchListJSONLpush(key string, value []interface{}) error { tempVal := []string{} for _, val := range value { temp, err := json.Marshal(val) if err != nil { log.Error("SetMuchListJSONLpush fail,reason:%v", err) return err } if err == nil { tempVal = append(tempVal, string(temp)) } } return slf.setList(key, tempVal, "LPUSH") } //GoSetListRpush ... func (slf *RedisModule) GoSetListRpush(key, value string, retErr *RetError) { tempVal := []string{value} slf.gosetList(key, tempVal, "RPUSH", retErr) } //SetListRpush ... func (slf *RedisModule) SetListRpush(key, value string) error { tempVal := []string{value} err := slf.setList(key, tempVal, "RPUSH") return err } //SetMuchRedisListRpush ... func (slf *RedisModule) SetMuchListRpush(key string, value []string) error { return slf.setList(key, value, "RPUSH") } //GoSetMuchRedisListRpush ... func (slf *RedisModule) GoSetMuchListRpush(key string, value []string, retErr *RetError) { slf.gosetList(key, value, "RPUSH", retErr) } //SetRedisListJSONRpush ... func (slf *RedisModule) SetListJSONRpush(key string, value interface{}) error { temp, err := json.Marshal(value) if err == nil { tempVal := []string{string(temp)} err = slf.setList(key, tempVal, "RPUSH") } else { log.Error("SetListJSONRpush fail,reason:%v", err) } return err } //GoSetRedisListJSONRpush ... func (slf *RedisModule) GoSetListJSONRpush(key string, value interface{}, retErr *RetError) { temp, err := json.Marshal(value) if err == nil { tempVal := []string{string(temp)} slf.gosetList(key, tempVal, "RPUSH", retErr) } else { if err != nil { retErr.resultChan = make(chan error, 1) retErr.resultChan <- err } } } //SetMuchRedisListJSONRpush ... func (slf *RedisModule) SetMuchListJSONRpush(key string, value []interface{}) error { tempVal := []string{} for _, val := range value { if temp, err := json.Marshal(val); err == nil { tempVal = append(tempVal, string(temp)) } } return slf.setList(key, tempVal, "RPUSH") } //GoSetMuchRedisListJSONRpush ... func (slf *RedisModule) GoSetMuchListJSONRpush(key string, value []interface{}, retErr *RetError) { tempVal := []string{} for _, val := range value { if temp, err := json.Marshal(val); err == nil { tempVal = append(tempVal, string(temp)) } } slf.gosetList(key, tempVal, "RPUSH", retErr) } // Lrange ... func (slf *RedisModule) Lrange(key string, start, end int) ([]string, error) { conn, err := slf.getConn() if err != nil { return nil, err } defer conn.Close() reply, err := conn.Do("lrange", key, start, end) if err != nil { log.Error("SetListJSONRpush fail,reason:%v", err) return nil, err } return redis.Strings(reply, err) } //获取List的长度 func (slf *RedisModule) GetListLen(key string) (int, error) { conn, err := slf.getConn() if err != nil { return -1, err } defer conn.Close() reply, err := conn.Do("LLEN", key) if err != nil { log.Error("GetListLen fail,reason:%v", err) return -1, err } return redis.Int(reply, err) } //弹出List最后条记录 func (slf *RedisModule) RPOPListValue(key string) error { conn, err := slf.getConn() if err != nil { return err } defer conn.Close() _, err = conn.Do("RPOP", key, 100) if err != nil { log.Error("RPOPListValue fail,reason:%v", err) return err } return nil } //弹出List最后条记录 func (slf *RedisModule) LtrimList(key string, start, end int) error { conn, err := slf.getConn() if err != nil { return err } defer conn.Close() _, err = conn.Do("LTRIM", key, start, end) if err != nil { log.Error("LtrimListValue fail,reason:%v", err) return err } return nil } //有序集合插入Json func (slf *RedisModule) ZADDInsertJson(key string, score float64, value interface{}) error { conn, err := slf.getConn() if err != nil { return err } defer conn.Close() JsonValue, err := json.Marshal(value) if err != nil { return err } _, err = conn.Do("ZADD", key, score, JsonValue) if err != nil { log.Error("ZADDInsertJson fail,reason:%v", err) return err } return nil } //有序集合插入 func (slf *RedisModule) ZADDInsert(key string, score float64, Data interface{}) error { conn, err := slf.getConn() if err != nil { return err } defer conn.Close() _, err = conn.Do("ZADD", key, score, Data) if err != nil { log.Error("ZADDInsert fail,reason:%v", err) return err } return nil } type ZSetDataWithScore struct { Data json.RawMessage `json:"data"` Score float64 `json:"score"` } func (slf *RedisModule) ZRangeJSON(key string, start, stop int, ascend bool, withScores bool, data interface{}) error { if withScores { if _, ok := data.(*[]ZSetDataWithScore); !ok { return errors.New("withScores must decode by []ZSetDataWithScore") } } b, err := slf.ZRange(key, start, stop, ascend, withScores) if err != nil { return err } err = json.Unmarshal(b, data) if err != nil { return err } return nil } //取有序set指定排名 ascend=true表示按升序遍历 否则按降序遍历 func (slf *RedisModule) ZRange(key string, start, stop int, ascend bool, withScores bool) ([]byte, error) { conn, err := slf.getConn() if err != nil { return nil, err } defer conn.Close() cmd := "ZREVRANGE" if ascend { cmd = "ZRANGE" } var reply interface{} if withScores { reply, err = conn.Do(cmd, key, start, stop, "WITHSCORES") } else { reply, err = conn.Do(cmd, key, start, stop) } if err != nil { return nil, err } return makeListJson(reply.([]interface{}), withScores), nil } //获取有序集合长度 func (slf *RedisModule) Zcard(key string) (int, error) { conn, err := slf.getConn() if err != nil { return 0, err } defer conn.Close() reply, err := conn.Do("ZCARD", key) if err != nil { return 0, err } return int(reply.(int64)), nil } //["123","234"] func makeListJson(redisReply []interface{}, withScores bool) []byte { var buf bytes.Buffer buf.WriteString("[") data := true for i, v := range redisReply { if i > 0 { buf.WriteString(",") } if !withScores { buf.WriteString(fmt.Sprintf("%s", v)) } else { if data { buf.WriteString("{") buf.WriteString(`"data":`) buf.WriteString(fmt.Sprintf("%s", v)) } else { buf.WriteString(`"score":`) buf.WriteString(fmt.Sprintf("%s", v)) buf.WriteString("}") } data = !data } } buf.WriteString("]") return buf.Bytes() } func (slf *RedisModule) ZRangeByScoreJSON(key string, start, stop float64, ascend bool, withScores bool, data interface{}) error { if withScores { if _, ok := data.(*[]ZSetDataWithScore); !ok { return errors.New("withScores must decode by []ZSetDataWithScore") } } b, err := slf.ZRangeByScore(key, start, stop, ascend, withScores) if err != nil { return err } err = json.Unmarshal(b, data) if err != nil { return err } return nil } func (slf *RedisModule) ZRangeByScore(key string, start, stop float64, ascend bool, withScores bool) ([]byte, error) { conn, err := slf.getConn() if err != nil { return nil, err } defer conn.Close() cmd := "ZREVRANGEBYSCORE" if ascend { cmd = "ZRANGEBYSCORE" } var reply interface{} if withScores { reply, err = conn.Do(cmd, key, start, stop, "WITHSCORES") } else { reply, err = conn.Do(cmd, key, start, stop) } if err != nil { return nil, err } return makeListJson(reply.([]interface{}), withScores), nil } //获取指定member的排名 func (slf *RedisModule) ZScore(key string, member interface{}) (float64, error) { conn, err := slf.getConn() if err != nil { return -1, err } defer conn.Close() cmd := "ZSCORE" var reply interface{} reply, err = conn.Do(cmd, key, member) if err != nil { return -1, err } return redis.Float64(reply, err) } //获取指定member的排名 func (slf *RedisModule) ZRank(key string, member interface{}, ascend bool) (int, error) { conn, err := slf.getConn() if err != nil { return -1, err } defer conn.Close() cmd := "ZREVRANK" if ascend { cmd = "ZRANK" } var reply interface{} reply, err = conn.Do(cmd, key, member) if err != nil { return -1, err } return redis.Int(reply, err) } func (slf *RedisModule) ZREMRANGEBYSCORE(key string, start, stop interface{}) error { conn, err := slf.getConn() if err != nil { return err } defer conn.Close() _, err = conn.Do("ZREMRANGEBYSCORE", key, start, stop) if err != nil { return err } return err } func (slf *RedisModule) ZREM(key string, member interface{}) (int, error) { conn, err := slf.getConn() if err != nil { return 0, err } defer conn.Close() reply, err := conn.Do("ZREM", key, member) return redis.Int(reply, err) } func (slf *RedisModule) ZREMMulti(key string, member ...interface{}) (int, error) { conn, err := slf.getConn() if err != nil { return 0, err } defer conn.Close() args := []interface{}{key} args = append(args, member...) reply, err := conn.Do("ZREM", args...) return redis.Int(reply, err) } func (slf *RedisModule) LRangeJSON(key string, start, stop int, data interface{}) error { b, err := slf.LRange(key, start, stop) if err != nil { return err } err = json.Unmarshal(b, data) if err != nil { return err } return nil } func (slf *RedisModule) LRange(key string, start, stop int) ([]byte, error) { conn, err := slf.getConn() if err != nil { return nil, err } defer conn.Close() reply, err := conn.Do("LRANGE", key, start, stop) if err != nil { return nil, err } return makeListJson(reply.([]interface{}), false), nil } //弹出list(消息队列)数据,数据放入out fromLeft表示是否从左侧弹出 block表示是否阻塞 timeout表示阻塞超时 func (slf *RedisModule) ListPopJson(key string, fromLeft, block bool, timeout int, out interface{}) error { b, err := slf.ListPop(key, fromLeft, block, timeout) if err != nil { return err } err = json.Unmarshal(b, out) if err != nil { return err } return nil } //弹出list(消息队列)数据 fromLeft表示是否从左侧弹出 block表示是否阻塞 timeout表示阻塞超时 func (slf *RedisModule) ListPop(key string, fromLeft, block bool, timeout int) ([]byte, error) { cmd := "" if fromLeft { if block { cmd = "BLPOP" } else { cmd = "LPOP" } } else { if block { cmd = "BRPOP" } else { cmd = "RPOP" } } conn, err := slf.getConn() if err != nil { return nil, err } defer conn.Close() reply, err := conn.Do(cmd, key, timeout) if err != nil { return nil, err } if reply == nil { err = errors.New("ListPop key is not exist!") return nil, err } b, ok := reply.([]byte) if !ok { err = errors.New("ListPop redis data is error") //service.GetLogger().Printf(service.LEVER_ERROR, "GetString redis data is error") return nil, err } return b, nil } func (slf *RedisModule) HincrbyHashInt(redisKey, hashKey string, value int) error { if redisKey == "" || hashKey == "" { return errors.New("Key Is Empty") } conn, err := slf.getConn() if err != nil { return err } defer conn.Close() _, retErr := conn.Do("HINCRBY", redisKey, hashKey, value) if retErr != nil { log.Error("HincrbyHashInt fail,reason:%v", retErr) } return retErr } func (slf *RedisModule) EXPlREInsert(key string, TTl int) error { conn, err := slf.getConn() if err != nil { return err } defer conn.Close() _, err = conn.Do("expire", key, TTl) if err != nil { log.Error("expire fail,reason:%v", err) return err } return nil } func (slf *RedisModule) Zremrangebyrank(redisKey string, start, end interface{}) (int, error) { conn, err := slf.getConn() if err != nil { return 0, err } defer conn.Close() reply, err := conn.Do("ZREMRANGEBYRANK", redisKey, start, end) return redis.Int(reply, err) } func (slf *RedisModule) Keys(key string) ([]string, error) { conn, err := slf.getConn() if err != nil { return nil, err } defer conn.Close() ret, err := conn.Do("KEYS", key) if err != nil { log.Error("KEYS fail, reason:%v", err) return nil, err } retList, ok := ret.([]interface{}) if !ok { err = errors.New("Func[KEYS] Redis Data Error") return nil, err } strs := []string{} for _, val := range retList { strVal, ok := val.([]byte) if !ok { return nil, fmt.Errorf("value not string") } strs = append(strs, string(strVal)) } return strs, nil }