renzheng 3 years ago
parent
commit
1911219e02
3 changed files with 282 additions and 23 deletions
  1. 184 0
      redis/goredis.go
  2. 88 22
      redis/redis.go
  3. 10 1
      redis/redis_test.go

+ 184 - 0
redis/goredis.go

@@ -0,0 +1,184 @@
+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
+}

+ 88 - 22
redis/redis.go

@@ -2,37 +2,103 @@ package redis
 
 
 import (
 import (
 	"context"
 	"context"
-	"fmt"
+	"encoding/json"
+	"log"
+	"runtime"
+	"strings"
+	"time"
 
 
 	"github.com/go-redis/redis/v8"
 	"github.com/go-redis/redis/v8"
 )
 )
 
 
-var ctx = context.Background()
+//"other=127.0.0.1:2203,push=127.0.0.1:2203,sso=172.17.4.83:1711"
+//"other=127.0.0.1:2203=0,push=127.0.0.1:2203,sso=172.17.4.83:1711"
 
 
-func Init() {
-	rdb := redis.NewClient(&redis.Options{
-		Addr:     "152.70.157.245:13301",
-		Password: "",
-		DB:       0,
-	})
+var (
+	ctx       = context.Background()
+	RedisPool map[string]*redis.Client
+)
 
 
-	err := rdb.Set(ctx, "key", "value", 0).Err()
-	if err != nil {
-		panic(err)
-	}
+type RedisUtil interface {
+	Init(opt interface{})
+	Put(key string, val interface{}) //单个存放
+	// Get(key string)                          //单个获取
+	// GetByPattern(key string)                 //根据正则获取
+	// BulkPut(timeout int, obj ...interface{}) //批量存储
+	// BulkGet(key ...string)                   //批量获取
+	// Expire(key string, expire int)           //设置过期
+	// Exists(key string)                       //是否存在
+	// FlushDB(dbnum ...int)                    //清空
+	// Del(key ...interface{})                  //删除key
+	// DelByPattern(key ...string)              //根据正则删除
+	// Incr(key string)                         //自增
+	// Decr(key string, val int)                //自减
+	// Pop(key string)                          //移除并获取某个key
+	// LPOP(list string)                        //移出并获取列表的第一个元素
+	// RPUSH(list string, val interface{})      //在列表中添加一个或多个值
+	// LLEN(list string)                        //获取列表长度
+
+}
 
 
-	val, err := rdb.Get(ctx, "key").Result()
-	if err != nil {
-		panic(err)
+func InitRedis(addrs string) {
+	InitRedisBySize(addrs, 80, 10, 240)
+}
+
+func InitRedisBySize(addrs string, maxSize, maxIdle, timeout int) {
+	RedisPool = map[string]*redis.Client{}
+	addr := strings.Split(addrs, ",")
+	for _, v := range addr {
+		saddr := strings.Split(v, "=")
+		RedisPool[saddr[0]] = redis.NewClient(&redis.Options{
+			Addr:         saddr[1],
+			Password:     "",
+			DB:           0,
+			PoolSize:     maxSize,
+			MinIdleConns: maxIdle,
+			IdleTimeout:  time.Duration(timeout) * time.Second,
+		})
 	}
 	}
-	fmt.Println("key", val)
+}
+
+//并存入字符串缓存
+func PutKV(key string, obj interface{}) bool {
+	return Put("other", key, obj, -1)
+}
+func PutCKV(code, key string, obj interface{}) bool {
+	return Put(code, key, obj, -1)
+}
+func Put(code, key string, obj interface{}, timeout int) bool {
+	b := false
+	defer catch()
 
 
-	val2, err := rdb.Get(ctx, "key2").Result()
-	if err == redis.Nil {
-		fmt.Println("key2 does not exist")
-	} else if err != nil {
-		panic(err)
+	var err error
+	_obj, _err := json.Marshal(obj)
+	if _err != nil {
+		log.Println("redisutil-SET-序列化出错Error", _err)
+		return b
+	}
+	if timeout < 1 {
+		_, err = RedisPool[code].Set(ctx, key, _obj, 0).Result()
+	} else {
+		_, err = RedisPool[code].SetEX(ctx, key, _obj, time.Duration(timeout)*time.Second).Result()
+	}
+	if nil != err {
+		log.Println("redisutil-SETError-put", err)
 	} else {
 	} else {
-		fmt.Println("key2", val2)
+		b = true
+	}
+	return b
+}
+
+func catch() {
+	if r := recover(); r != nil {
+		log.Println(r)
+		for skip := 0; ; skip++ {
+			_, file, line, ok := runtime.Caller(skip)
+			if !ok {
+				break
+			}
+			go log.Printf("%v,%v\n", file, line)
+		}
 	}
 	}
 }
 }

+ 10 - 1
redis/redis_test.go

@@ -1,9 +1,18 @@
 package redis
 package redis
 
 
 import (
 import (
+	"log"
 	"testing"
 	"testing"
 )
 )
 
 
 func TestInit(t *testing.T) {
 func TestInit(t *testing.T) {
-	Init()
+	// regAddr := regexp.MustCompile("[0-9.a-zA-Z/]+:[0-9]+.*")
+	// log.Println(regAddr.MatchString("fdfsd.uyuyds.ii:2203&dsds"))
+	r1 := &GoRedis{}
+	// r1.Init("other=127.0.0.1:2203|127.0.0.1:2204=0-14=1-10=400")
+	// r1.Init("other=127.0.0.1:2203=0-1=1-10=400")
+	// r1.Init("other=127.0.0.1:2203=1=1")
+	r1.Init("192.168.3.207:6379=1-4=2=600")
+	r1.Put(`ddd1`, "fff")
+	log.Println(hashCode("aaaaOppkdlkj9i9)Jkjfdksfhjhajkhdsa8d98uiuhjkdsnjknbaaa4554645654645ajjjhh12uih"))
 }
 }