123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- 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
- }
|