1.初始化redis
type RedisConf struct {Hostname stringHostport stringPassword stringMaxIdleConns intMaxOpenConns intMaxLifeTime int
}func GetPool(conf *RedisConf) *redis.Pool {return &redis.Pool{Dial: func() (conn redis.Conn, err error) {c, err := redis.Dial("tcp", conf.Hostname+":"+conf.Hostport,redis.DialConnectTimeout(time.Second*3),redis.DialReadTimeout(time.Second*3),redis.DialWriteTimeout(time.Second*3),)if err != nil {return nil, err}if conf.Password != "" { // 有可能没有密码if _, err := c.Do("AUTH", conf.Password); err != nil {c.Close()return nil, err}}return c, nil},MaxIdle: conf.MaxIdleConns, // 最初的连接数量MaxActive: conf.MaxOpenConns, // 连接池最大连接数量,不确定可以用0(0表示自动定义,按需分配)IdleTimeout: time.Duration(conf.MaxLifeTime) * time.Second, // 连接关闭时间100秒(100秒不使用将关闭)Wait: true, // 超过最大连接,是报错,还是等待TestOnBorrow: func(c redis.Conn, t time.Time) error {if time.Since(t) < time.Minute {return nil}_, err := c.Do("PING")return err},}
}func NewRedis(conf *RedisConf) *goRedis.Client {newClient := goRedis.NewClient(&goRedis.Options{Addr: fmt.Sprintf("%s:%s", conf.Hostname, conf.Hostport),Password: conf.Password,DialTimeout: time.Second * 3,ReadTimeout: time.Second * 3,WriteTimeout: time.Second * 3,PoolSize: conf.MaxIdleConns,MaxActiveConns: conf.MaxOpenConns,ConnMaxIdleTime: time.Duration(conf.MaxLifeTime) * time.Second,})return newClient
}
2.分布式锁
func RedLock(redPool *redis.Pool, Key string, exprTime time.Duration) (*redsync.Mutex, error) {r := redsync.New(redigo.NewPool(redPool))mutex := r.NewMutex(Key, redsync.WithExpiry(exprTime), redsync.WithTries(32))if err := mutex.Lock(); err != nil {log.Errorf("RedLock err: %s", err.Error())return nil, err}fmt.Println(fmt.Sprintf("accountLock success Key:%s", Key))return mutex, nil
}func RedUnLock(mutex *redsync.Mutex) {i := 0
loop:unlock, err := mutex.Unlock()if err != nil || !unlock {i += 1if i <= 2 {time.Sleep(200 * time.Millisecond)goto loop}log.Errorf("redsync.SetMutex err: %v, name:%v", err, mutex.Name())return}
}