Go操作Redis封裝的方法


測試項目目錄

項目代碼

operates.go

package redisOperate

import (
    "errors"
    "github.com/garyburd/redigo/redis"
    "math"
    "time"
)


type RRedis struct {
    redisCli       *redis.Pool
    maxIdle        int
    maxActive      int
    maxIdleTimeout time.Duration
    maxTimeout     time.Duration
    lazyLimit      bool
    maxSize        int
}

// 從池里獲取連接 ———— 單獨的方法
func (r *RRedis) getRedisConn() redis.Conn {
    rc := r.redisCli.Get()
    // // 用完后將連接放回連接池
    // defer rc.Close()
    return rc
}

// GetAllKeys 獲取所有keys
func (r *RRedis) GetAllKeys() []string {

    rc := r.getRedisConn()
    defer rc.Close()

    keys, err := redis.Strings(rc.Do("KEYS", "*"))
    if err != nil {
        return make([]string, 0)
    }
    return keys
}

func (r *RRedis) Get(key string, timeout int) (string, error) {

    start := time.Now()

    for {
        res, err := r.GetNoWait(key)
        if err != nil {
            return "", err
        } else if res == "" {
            if timeout != -1 {
                lasted := time.Now().Sub(start)
                if r.maxTimeout > lasted {
                    t1 := r.maxTimeout
                    t2 := time.Duration(timeout)*time.Second - lasted
                    time.Sleep(time.Duration(math.Min(float64(t1), float64(t2))))
                } else {
                    return "", errors.New("GET timeout")
                }
            } else {
                time.Sleep(r.maxTimeout)
            }
        } else {
            return res, nil
        }
    }
}

func (r *RRedis) GetNoWait(key string) (string, error) {

    rc := r.getRedisConn()
    defer rc.Close()

    res, err := redis.String(rc.Do("LPOP", key))

    if err != nil {
        return "", err
    }
    return res, nil
}

func (r *RRedis) Put(key string, value string, timeout int) (int, error) {

    start := time.Now()

    for {
        res, err := r.PutNoWait(key, value)

        if err != nil {
            return 0, err
        } else if res == -1 {
            if timeout != -1 {
                lasted := time.Now().Sub(start)
                if r.maxTimeout > lasted {
                    t1 := r.maxTimeout
                    t2 := time.Duration(timeout)*time.Second - lasted
                    time.Sleep(time.Duration(math.Min(float64(t1), float64(t2))))
                } else {
                    return 0, errors.New("PUT timeout")
                }
            } else {
                time.Sleep(r.maxTimeout)
            }

        } else {
            return res, nil
        }

    }
}

func (r *RRedis) PutNoWait(key string, value string) (int, error) {

    rc := r.getRedisConn()
    defer rc.Close()

    if r.Full(key) {
        return -1, nil
    }

    res, err := redis.Int(rc.Do("RPUSH", key, value))
    if err != nil {
        return 0, err
    }
    return res, nil
}

func (r *RRedis) QSize(key string) int {

    rc := r.getRedisConn()
    defer rc.Close()

    res, err := redis.Int(rc.Do("LLEN", key))
    if err != nil {
        return -1
    }

    return res
}

func (r *RRedis) Empty(key string) bool {

    rc := r.getRedisConn()
    defer rc.Close()

    res, err := redis.Int(rc.Do("LLEN", key))
    if err != nil {
        return false
    }
    if res == 0 {
        return true
    }
    return false
}

func (r *RRedis) Full(key string) bool {

    if r.maxSize != 0 && r.QSize(key) >= r.maxSize {
        return true
    }

    return false
}
operates.go

redisInter.go

package redisOperate

import (
    "github.com/garyburd/redigo/redis"
    "time"
)

// 父級interface
type RedisFatherInterface interface {
    // 獲取所有keys
    GetAllKeys() []string
}



// ListInterface 操作list接口
type ListInterface interface {
    // "繼承"父類的所有方法
 RedisFatherInterface
    GetNoWait(key string) (string, error) // ~di: interface{}類型、數據壓縮
    Get(key string, timeout int) (string, error)
    Put(key string, value string, timeout int) (int, error)
    PutNoWait(key string, value string) (int, error)
    QSize(key string) int
    Empty(key string) bool
    Full(key string) bool
}


// redis所有操作的接口
type RedisInterface interface {
    ListInterface
}


// 工廠函數,要求對應的結構體必須實現 RedisInterface 中的所有方法
// 如果只想實現某一些方法,就返回"有這些方法的結構體"就好了
func ProduceRedis(host, port, password string, db, maxSize int, lazyLimit bool) (RedisInterface, error) {
    
    // 要求RRedis結構體實現返回的接口中所有的方法!
    redisObj := &RRedis{
        maxIdle:        100,
        maxActive:      130,
        maxIdleTimeout: time.Duration(60) * time.Second,
        maxTimeout:     time.Duration(30) * time.Second,
        lazyLimit:      lazyLimit,
        maxSize:        maxSize,
    }
    // 建立連接池
    redisObj.redisCli = &redis.Pool{
        MaxIdle:     redisObj.maxIdle,
        MaxActive:   redisObj.maxActive,
        IdleTimeout: redisObj.maxIdleTimeout,
        Wait:        true,
        Dial: func() (redis.Conn, error) {
            con, err := redis.Dial(
                "tcp",
                host+":"+port, // address
                redis.DialPassword(password),
                redis.DialDatabase(int(db)),
                redis.DialConnectTimeout(redisObj.maxTimeout),
                redis.DialReadTimeout(redisObj.maxTimeout),
                redis.DialWriteTimeout(redisObj.maxTimeout),
            )
            if err != nil {
                return nil, err
            }
            return con, nil
        },
    }

    return redisObj, nil
}

main.go

package main

import (
    "fmt"
    red "ginProjects/redisOperate"
)

func main() {
// 測試redis的操作 testRedisOperate() } // 測試redis的操作 func testRedisOperate(){ redisCLi, err := red.ProduceRedis("127.0.0.1","6388","",0,100,true) if err != nil{ fmt.Println("redis連接錯誤!err>>>",err.Error()) return } // 獲取所有keys allKeysLst := redisCLi.GetAllKeys() fmt.Print("key>>> ",allKeysLst) }

~~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM