package redis import ( "context" "hash/crc32" "log" "math" "regexp" "strconv" "strings" "time" "github.com/go-redis/redis/v8" ) type GoRedis struct { Addr string Password string Code string DB int DBS []int //数据库列表 HashDb bool //是否是多个数据库 PoolSize int MinIdleConns int IdleTimeout int Ctx context.Context C *redis.Client BakDb bool //是否有备用节点 Bak *GoRedis //备用节点连接 } //初始化单个"[other=]127.0.0.1:2203|127.0.0.1:2204=0-1=1-10=300" [代码]、地址[|备用地址,&集群地址]、库、最大池、空闲时间默认300秒 func (r *GoRedis) Init(opt interface{}) { check := false code, addr, dbs, pool, idle := "", "", []int{0}, []int{2, 30}, 300 if so, ok := opt.(string); ok { arr := strings.Split(so, "=") regAddr := regexp.MustCompile("[0-9.a-zA-Z/]+:[0-9]+.*") if len(arr) == 1 { if regAddr.MatchString(arr[0]) { check = true addr = arr[0] } } else if len(arr) > 1 { index := 0 if regAddr.MatchString(arr[0]) { index = 1 addr = arr[0] check = true } else if regAddr.MatchString(arr[1]) { check = true addr = arr[1] code = arr[0] } //解析库配置 if len(arr) > 2-index { //dbs配置 dbs1 := strings.Split(arr[2-index], "-") if len(dbs1) == 1 || len(dbs1) == 2 { check = true dbs[0], _ = strconv.Atoi(dbs1[0]) if len(dbs1) == 2 { tmp, _ := strconv.Atoi(dbs1[1]) dbs = append(dbs, tmp) } } else { check = false } //解析连接池配置 if len(arr) > 3-index { pool1 := strings.Split(arr[3-index], "-") if len(pool1) == 1 || len(pool1) == 2 { check = true if len(pool1) == 1 { pool[1], _ = strconv.Atoi(pool1[0]) pool[0] = int(math.Ceil(float64(pool[1]) * 0.2)) } else { pool[0], _ = strconv.Atoi(pool1[0]) pool[1], _ = strconv.Atoi(pool1[1]) } } else { check = false } //解析最大空闲时间配置 if len(arr) > 4-index { idle, _ = strconv.Atoi(arr[4-index]) if idle == 0 { idle = 300 } } } } } } else if _, ok := opt.(map[string]interface{}); ok { } if check { addrs := strings.Split(addr, "|") r.Addr = addrs[0] r.Code = code r.DB = dbs[0] //DBS []int r.PoolSize = pool[1] r.MinIdleConns = pool[0] r.IdleTimeout = idle r.Ctx = context.Background() r.C = redis.NewClient(&redis.Options{ Addr: r.Addr, DB: r.DB, PoolSize: r.PoolSize, MinIdleConns: r.MinIdleConns, IdleTimeout: time.Duration(r.IdleTimeout) * time.Second, }) if len(dbs) > 1 { r.HashDb = true r.DBS = []int{} for i := dbs[0]; i <= dbs[1]; i++ { r.DBS = append(r.DBS, i) } } if len(addrs) == 2 { r.BakDb = true //有备用节点,集群先不考虑 r.Bak = &GoRedis{} r.Bak.Addr = addrs[1] r.Bak.Code = code r.Bak.DB = dbs[0] r.Bak.DBS = r.DBS r.Bak.HashDb = r.HashDb r.Bak.PoolSize = pool[1] r.Bak.MinIdleConns = pool[0] r.Bak.IdleTimeout = idle r.Bak.Ctx = context.Background() r.Bak.C = redis.NewClient(&redis.Options{ Addr: r.Bak.Addr, DB: r.Bak.DB, PoolSize: r.Bak.PoolSize, MinIdleConns: r.Bak.MinIdleConns, IdleTimeout: time.Duration(r.Bak.IdleTimeout) * time.Second, }) } } log.Println(check, code, addr, dbs, pool, idle, r.DBS) } func NewGoRedis(Addr, Password, Code string, DB, PoolSize, MinIdleConns, IdleTimeout int) *GoRedis { r := &GoRedis{} r.C = redis.NewClient(&redis.Options{ Addr: Addr, Password: Password, DB: DB, PoolSize: PoolSize, MinIdleConns: MinIdleConns, IdleTimeout: time.Duration(IdleTimeout) * time.Second, }) return r } func (r *GoRedis) Put(key string, val interface{}) { var stutsCmd *redis.StatusCmd if r.HashDb { //有多个库 r.selectDB(key) stutsCmd = r.C.Set(r.Ctx, key, val, 0) } else { stutsCmd = r.C.Set(r.Ctx, key, val, 0) } str, err := stutsCmd.Result() log.Println(str, err) } //此处切换失败!!!,只能切换取到的连接,不会切换Client,待验证 func (r *GoRedis) selectDB(key string) { db := r.DBS[hashCode(key)%len(r.DBS)] //取存哪个db,可以提取出来一个方法 r.C.Conn(r.Ctx).Select(r.Ctx, db) //切换数据库 } func hashCode(key string) int { v := int(crc32.ChecksumIEEE([]byte(key))) if v < 0 { v = -v } return v }