golang 初始化Redis的连接池

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang 初始化Redis的连接池相关的知识,希望对你有一定的参考价值。


//调用Redis前必须初始化该方法
func Init(service string) {
	// 获取全部redis address
	hosts, err := utils.AllBns(service)
	if err != nil {
		log.Warn("get_redis_host_by_bns_fail: ", err)
		return
	}
	log.Debug("redis_hosts: ", hosts)
	// 写入配置及对应的连接池,添加到slice中
	redises := make([]internalRedis, len(hosts))
	for idx, host := range hosts {
		conf := RedisConfig{
			HostPort:    host,
			MaxIdle:     25,
			MaxActive:   25,
			IdleTimeout: 2400,
			Passwd:      "",
			Database:    0,
			Timeout:     5,
		}
		redises[idx] = internalRedis{
			config: conf,
			pool:   getPool(conf),
		}
	}
	//5.写入全局变量并获取连接池
	serviceMap[service] = Redis{
		Service:         service,
		internalRedises: redises,
	}
}

func getPool(conf RedisConfig) *redis.Pool {
	return &redis.Pool{
		MaxIdle:     conf.MaxIdle,
		MaxActive:   conf.MaxActive,
		IdleTimeout: conf.IdleTimeout * time.Second,
		Wait:        true,
		Dial: func() (conn redis.Conn, e error) {
			con, err := redis.Dial("tcp", conf.HostPort,
				redis.DialPassword(conf.Passwd),
				redis.DialDatabase(conf.Database),
				redis.DialConnectTimeout(conf.Timeout*time.Second),
				redis.DialReadTimeout(conf.Timeout*time.Second),
				redis.DialWriteTimeout(conf.Timeout*time.Second),
			)

			if err != nil {
				log.Warn("get_redis_conn_fail: ", err)
				return nil, err
			}
			return con, 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 (objRedis *Redis) getConn() (redis.Conn, error) {
	defer func() {
		if err := recover(); err != nil {
			log.Panicf("Redis getConn err : %s", err)
		}
	}()
	redises := objRedis.internalRedises
	redisesLen := uint64(len(redises))
	if redisesLen == 0 {
		return nil, errors.New("Invalid redis host list")
	}

	tryCount := 0
	for tryCount < 3 {
		tryCount++
		indexIncr := atomic.AddUint64(&redisRoundRobinCurrent, 1)
		index := indexIncr % redisesLen
		redisConn := redises[index]
		conn := redisConn.getConn()
		if _, err := conn.Do("ping"); err != nil {
			log.Warn("redis host conn fail: ", redisConn.config)
			conn.Close()
			continue
		}
		return conn, nil
	}
	return nil, errors.New("cache conn fail")
}

// 获取连接
func (redis *internalRedis) getConn() redis.Conn {
	conn := redis.pool.Get()
	return conn
}

golang总结-Redis整合

go get github.com/gomodule/redigo/redis

1. 基本用法

  1. 获取连接
package conn

import (
    "github.com/gomodule/redigo/redis"
    "log"
)

const (
    redis_passwd = ""
    redis_host = ""
    redis_port = ""
    redis_address = "192.168.2.130:6379"
)

func getConn() redis.Conn {
    conn, err := redis.Dial("tcp", redis_address)
    if err != nil {
        log.Println("redis connect err", err)
        panic(err)
    }
    return conn
}
  1. 操作redis
package conn

import (
    "fmt"
    "github.com/gomodule/redigo/redis"
    "log"
)

var c = getConn()

//string 操作

func Set(key string, value interface{}) bool {
    defer c.Close()
    _, err := c.Do("set", key, value)
    if err != nil {
        log.Println("set a value error,", err)
        return false
    }
    return true
}


func Get(key string) string {
    defer c.Close()
    value, err := redis.String(c.Do("get", key))
    if err != nil {
        log.Println("get a value error,", err)
        return ""
    }

    return value
}

func Del(key string) bool {
    defer c.Close()
    _, err := c.Do("del", key)
    if err != nil {
        log.Println("del a key error, ", err)
        return false
    }
    return true
}

//Hash操作
func HashSet(key string, data map[string]interface{}) {
    defer c.Close()
    for k, v := range data {
        _, err := c.Do("hset", key, k, v)
        if err != nil {
            log.Println("hset a error, ", err)
            continue
        }
    }
}

func HashMGet(key string) map[string]interface{} {
    defer c.Close()

    data := make(map[string]interface{})

    reply, err := redis.ByteSlices(c.Do("hgetall", key))
    if err != nil {
        log.Println("hmget error, ", err)
        return nil
    }
    for i, v := range reply {
        fmt.Println(string(v))
        if i % 2 == 0 {
            data[string(v)] = string(reply[i+1])
        }
        continue
    }
    return data

}

2. Redis连接池

package pool

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

var (
    pool *redis.Pool
)

const (
    redis_host = "192.168.2.130:6379"
)

func init() {
    pool = &redis.Pool{
        MaxIdle: 10,
        MaxActive: 0, //0表示没有限制
        IdleTimeout: 1 * time.Second,
        Dial: func() (redis.Conn, error) {
            return redis.Dial("tcp", redis_host)
        },
    }
}

获取连接:conn := pool.Get()

以上是关于golang 初始化Redis的连接池的主要内容,如果未能解决你的问题,请参考以下文章

redis mysql 连接池 之 golang 实现

golang 如何连接redis --- 2022-04-03

golang redis连接池使用方法

golang redis事务 --- 2022-04-03

node.js中如何配置redis与连接池?

python 的 redis 库,连接池怎么用