Go---Redis连接池

之前一篇文章介绍过使用redigo连接redis数据库处理,在使用中发现如果初始化一条链接连接redis做相关操作,使用中发现当两个程序交替使用redis时,先前建立的链接会断掉,只能每次操作的时候重新建立链接,使用后关闭。后来发现redigo有一个连接池的功能,所以改用链接池处理

先介绍下链接池的结构

type Pool struct {
    //Dial 是创建链接的方法
    Dial func() (Conn, error)

    //TestOnBorrow 是一个测试链接可用性的方法
    TestOnBorrow func(c Conn, t time.Time) error

    // 最大的空闲连接数,表示即使没有redis连接时依然可以保持N个空闲的连接,而不被清除,随时处于待命状态
    MaxIdle int

    // 最大的激活连接数,表示同时最多有N个连接 ,为0事表示没有限制
    MaxActive int

    //最大的空闲连接等待时间,超过此时间后,空闲连接将被关闭
    IdleTimeout time.Duration

    // 当链接数达到最大后是否阻塞,如果不的话,达到最大后返回错误
    Wait bool

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

使用方法可以看下边的例子

package main

import (
    "flag"
    "fmt"
    "github.com/garyburd/redigo/redis"
    "time"
)
//声明一些全局变量
var (
    pool          *redis.Pool
    redisServer   = flag.String("redisServer", ":6379", "")
    redisPassword = flag.String("redisPassword", "123456", "")
)
//初始化一个pool
func newPool(server, password string) *redis.Pool {
    return &redis.Pool{
        MaxIdle:     3,
        MaxActive:   5,
        IdleTimeout: 240 * time.Second,
        Dial: func() (redis.Conn, error) {
            c, err := redis.Dial("tcp", server)
            if err != nil {
                return nil, err
            }
            if _, err := c.Do("AUTH", password); err != nil {
                c.Close()
                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")
            return err
        },
    }
}

func main() {
    flag.Parse()
    pool = newPool(*redisServer, *redisPassword)

    conn := pool.Get()
    defer conn.Close()
    //redis操作
    v, err := conn.Do("SET", "pool", "test")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(v)
    v, err = redis.String(conn.Do("GET", "pool"))
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(v)

}

方便使用也同样做了一个封装