golang 初始化Redis的连接池

Posted

tags: .net redis 连接池    .net sqlserver 2012 默认连接字符串连接池    @Controller默认连接池大小    .net SQLHelper 连接池    .net http 连接池   

篇首语:本文由小常识网(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的连接池的主要内容,如果未能解决你的问题,请参考以下文章