123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- 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))
- }
|