Tao Zhang 5 роки тому
коміт
90317d83ab
11 змінених файлів з 643 додано та 0 видалено
  1. 8 0
      .idea/.gitignore
  2. 5 0
      .idea/inspectionProfiles/profiles_settings.xml
  3. 6 0
      .idea/misc.xml
  4. 8 0
      .idea/modules.xml
  5. 9 0
      .idea/redis_util.iml
  6. 23 0
      README.md
  7. 8 0
      go.mod
  8. 8 0
      go.mod.bak
  9. 4 0
      go.sum
  10. 69 0
      redisloginutil.go
  11. 495 0
      redisutil.go

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/

+ 5 - 0
.idea/inspectionProfiles/profiles_settings.xml

@@ -0,0 +1,5 @@
+<component name="InspectionProjectProfileManager">
+  <settings>
+    <option name="PROJECT_PROFILE" />
+  </settings>
+</component>

+ 6 - 0
.idea/misc.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="JavaScriptSettings">
+    <option name="languageLevel" value="ES6" />
+  </component>
+</project>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/redis_util.iml" filepath="$PROJECT_DIR$/.idea/redis_util.iml" />
+    </modules>
+  </component>
+</project>

+ 9 - 0
.idea/redis_util.iml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+  <component name="Go" enabled="true" />
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 23 - 0
README.md

@@ -0,0 +1,23 @@
+# Redis go 封装
+这里引用了2个版本的驱动。(历史问题,其实功能重叠)<br/>
+github.com/garyburd/redigo 这个版本要老一些,更新也不频繁<br/>
+github.com/gomodule/redigo 这个版本活跃度更高些,建议后续使用(封装)这个版本<br/>
+## 功能介绍
+Redis go驱动封装,支持put/get,超时设置,list数据格式,mget等特性。
+## 使用说明
+### 简单样例
+`
+	InitRedis("sso=192.168.3.14:1379")
+	Put("sso", "1903540616", "oJULtwzXo6EFV1Ah-XeyRBimXGM8", 180)
+	log.Println(Get("1903540616", "A"))
+`
+### 函数声明
+`
+func PutKV(key string, obj interface{}) bool
+    PutKV 分流redis ,并存入字符串缓存 Output: bool 是否存储成功
+
+`
+
+## 版本变更
+
+## 注意事项

+ 8 - 0
go.mod

@@ -0,0 +1,8 @@
+module github.topsoft.com/BP/redis_util
+
+go 1.14
+
+require (
+	github.com/garyburd/redigo v1.6.0
+	github.com/gomodule/redigo v2.0.0+incompatible
+)

+ 8 - 0
go.mod.bak

@@ -0,0 +1,8 @@
+module app.yhyue.com/BP/redis_util
+
+go 1.14
+
+require (
+	github.com/garyburd/redigo v1.6.0
+	github.com/gomodule/redigo v2.0.0+incompatible
+)

+ 4 - 0
go.sum

@@ -0,0 +1,4 @@
+github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc=
+github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
+github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=
+github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=

+ 69 - 0
redisloginutil.go

@@ -0,0 +1,69 @@
+package redis_util
+import (
+	"log"
+	"strings"
+	"time"
+
+	redisLogin "github.com/gomodule/redigo/redis"
+)
+
+var RedisLoginPool *redisLogin.Pool
+
+func InitRedisLogin(addrs string) {
+	addr := strings.Split(addrs, ",")
+	for _, v := range addr {
+		saddr := strings.Split(v, "=")
+		if saddr[0] == "login" {
+			RedisLoginPool = &redisLogin.Pool{MaxActive: 10, MaxIdle: 5,
+				IdleTimeout: time.Duration(10) * time.Second, Dial: func() (redisLogin.Conn, error) {
+					c, err := redisLogin.Dial("tcp", saddr[1])
+					if err != nil {
+						return nil, err
+					}
+					return c, nil
+				}}
+		}
+	}
+
+}
+
+//
+func SetLoginVal(key, value string) {
+	conn := RedisLoginPool.Get()
+	defer conn.Close()
+	conn.Do("PUBLISH", key, value)
+}
+
+//
+func GetLoginVal(key string, wxFunc func(wxParams []string) bool) {
+	for {
+		defer catch()
+	L:
+		for {
+			conn := RedisLoginPool.Get()
+			defer conn.Close()
+			if conn.Err() == nil {
+				psc := redisLogin.PubSubConn{Conn: conn}
+				if err := psc.Subscribe(redisLogin.Args{}.AddFlat(key)...); err != nil {
+					log.Println(err)
+				}
+				for {
+					msg := psc.Receive()
+					//					go func(msg interface{}) {
+					switch n := msg.(type) {
+					case error:
+						log.Println("wxlogin err", msg)
+						break L
+					case redisLogin.Message:
+						res := string(n.Data)
+						param := strings.Split(res, ",")
+						go wxFunc(param)
+					}
+					//					}(msg)
+				}
+			}
+			time.Sleep(2 * time.Second)
+		}
+		time.Sleep(1 * time.Second)
+	}
+}

+ 495 - 0
redisutil.go

@@ -0,0 +1,495 @@
+/**
+redis_util Redis工具包<br/>
+作者:hongbo<br/>
+日期:2020-4-22<br/>
+*/
+package redis_util
+
+import (
+	"encoding/json"
+	"errors"
+	"log"
+	"runtime"
+	"strings"
+	"time"
+
+	redigo "github.com/garyburd/redigo/redis"
+)
+
+// RedisPool redis 多服务端连接池,1个应用同时连接多个redis服务
+var RedisPool map[string]*redigo.Pool
+
+// InitRedis 初始化redis 多端连接池 <br/>
+// @param addrs enterprise=192.168.3.14:1379,service=192.168.3.14:2379,other=192.168.3.14:3379
+func InitRedis(addrs string) {
+	InitRedisBySize(addrs, 300, 30, 240)
+}
+
+//初始化redis连接池,支持多个redis库
+func InitRedisBySize(addrs string, maxSize, maxIdle, timeout int) {
+	RedisPool = map[string]*redigo.Pool{}
+	addr := strings.Split(addrs, ",")
+	for _, v := range addr {
+		saddr := strings.Split(v, "=")
+		RedisPool[saddr[0]] = &redigo.Pool{MaxActive: maxSize, MaxIdle: maxIdle,
+			IdleTimeout: time.Duration(timeout) * time.Second, Dial: func() (redigo.Conn, error) {
+				return redigo.Dial("tcp", saddr[1])
+			}}
+	}
+}
+
+// PutKV  分流redis ,并存入字符串缓存
+// Output: bool 是否存储成功
+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()
+	conn := RedisPool[code].Get()
+	defer conn.Close()
+	var err error
+	_obj, _err := json.Marshal(obj)
+	if _err != nil {
+		log.Println("redisutil-SET-序列化出错Error", _err)
+		return b
+	}
+	if timeout < 1 {
+		_, err = conn.Do("SET", key, _obj)
+	} else {
+		_, err = conn.Do("SET", key, _obj, "EX", timeout)
+	}
+	if nil != err {
+		log.Println("redisutil-SETError-put", err)
+	} else {
+		b = true
+	}
+	return b
+}
+
+func BulkPut(code string, timeout int, obj ...interface{}) bool {
+	b := false
+	defer catch()
+	conn := RedisPool[code].Get()
+	defer conn.Close()
+	var err error
+	for _, _tmp := range obj {
+		tmp, ok := _tmp.([]interface{})
+		if ok && len(tmp) == 2 {
+			key, kok := tmp[0].(string)
+			if kok && key != "" {
+				_obj, _err := json.Marshal(tmp[1])
+				if _err != nil {
+					log.Println("redisutil-SET-序列化出错Error", _err)
+					return b
+				}
+				if timeout < 1 {
+					_, err = conn.Do("SET", key, _obj)
+				} else {
+					_, err = conn.Do("SET", key, _obj, "EX", timeout)
+				}
+			}
+		}
+	}
+	if nil != err {
+		b = false
+		log.Println("redisutil-SETError-put", err)
+	} else {
+		b = b && true
+	}
+	return b
+}
+
+//直接存字节流
+func PutBytes(code, key string, data *[]byte, timeout int) (err error) {
+	defer catch()
+
+	conn := RedisPool[code].Get()
+	defer conn.Close()
+
+	if timeout < 1 {
+		_, err = conn.Do("SET", key, *data)
+	} else {
+		_, err = conn.Do("SET", key, *data, "EX", timeout)
+	}
+	if nil != err {
+		log.Println("redisutil-SETError", err)
+	}
+	return
+}
+
+//设置超时时间,单位秒
+func SetExpire(code, key string, expire int) error {
+	defer catch()
+
+	conn := RedisPool[code].Get()
+	defer conn.Close()
+	_, err := conn.Do("expire", key, expire)
+	return err
+}
+
+//判断一个key是否存在
+func Exists(code, key string) (bool, error) {
+	defer catch()
+
+	conn := RedisPool[code].Get()
+	defer conn.Close()
+	repl, err := conn.Do("exists", key)
+	ret, _ := redigo.Int(repl, err)
+	return ret == 1, err
+}
+
+//获取string
+func GetStr(code, key string) string {
+	res := Get(code, key)
+	str, _ := res.(string)
+	return str
+}
+
+//获取int
+func GetInt(code, key string) int {
+	result, _ := GetNewInt(code, key)
+	return result
+}
+
+func GetNewInt(code, key string) (int, error) {
+	var res interface{}
+	err := GetNewInterface(code, key, &res)
+	var result int
+	if str, ok := res.(float64); ok {
+		result = int(str)
+	}
+	return result, err
+}
+
+//取得字符串,支持变参,2个 (key,code),返回后自己断言
+func Get(code, key string) (result interface{}) {
+	GetInterface(code, key, &result)
+	return
+}
+
+func GetInterface(code, key string, result interface{}) {
+	GetNewInterface(code, key, result)
+}
+
+func GetNewInterface(code, key string, result interface{}) error {
+	defer catch()
+	conn := RedisPool[code].Get()
+	defer conn.Close()
+	ret, err := conn.Do("GET", key)
+	if nil != err {
+		log.Println("redisutil-GetError", err)
+	} else {
+		var ok bool
+		var res []byte
+		if res, ok = ret.([]byte); ok {
+			err = json.Unmarshal(res, result)
+			if err != nil {
+				log.Println("Get ERROR:", err.Error())
+			}
+		}
+	}
+	return err
+}
+
+//直接返回字节流
+func GetBytes(code, key string) (ret *[]byte, err error) {
+	defer catch()
+
+	conn := RedisPool[code].Get()
+	defer conn.Close()
+	var r interface{}
+	r, err = conn.Do("GET", key)
+	if err != nil {
+		log.Println("redisutil-GetBytesError", err)
+	} else {
+		if tmp, ok := r.([]byte); ok {
+			ret = &tmp
+		} else {
+			err = errors.New("redis返回数据格式不对")
+		}
+	}
+	return
+}
+func GetNewBytes(code, key string) (ret *[]byte, err error) {
+	defer catch()
+	redisPool := RedisPool[code]
+	if redisPool == nil {
+		err = errors.New("redis code " + code + " is nil")
+		log.Println("redisutil-GetNewBytesError", err)
+		return
+	}
+	conn := redisPool.Get()
+	defer conn.Close()
+	var r interface{}
+	r, err = conn.Do("GET", key)
+	if err != nil {
+		log.Println("redisutil-GetNewBytesError", err)
+	} else if r != nil {
+		if tmp, ok := r.([]byte); ok {
+			ret = &tmp
+		}
+	}
+	return
+}
+
+//删所有key
+func FlushDB(code string) bool {
+	b := false
+	defer catch()
+
+	conn := RedisPool[code].Get()
+	defer conn.Close()
+
+	var err error
+	_, err = conn.Do("FLUSHDB")
+	if nil != err {
+		log.Println("redisutil-FLUSHDBError", err)
+	} else {
+		b = true
+	}
+	return b
+}
+
+//支持删除多个key
+func Del(code string, key ...interface{}) bool {
+	defer catch()
+	b := false
+	conn := RedisPool[code].Get()
+	defer conn.Close()
+
+	var err error
+	_, err = conn.Do("DEL", key...)
+	if nil != err {
+		log.Println("redisutil-DELError", err)
+	} else {
+		b = true
+	}
+	return b
+}
+
+//
+//func GetCacheByMgo(key, coll, sql, show string, ftype, timeout int) map[string]interface{} {
+//	obj := Get("", key)
+//	if nil == obj {
+//		switch ftype {
+//		case 1:
+//			m := mongodb.FindById(coll, sql, show)
+//			if m != nil && len(*m) > 0 {
+//				Put("", key, *m, timeout)
+//			}
+//			return *m
+//			break
+//		}
+//		return nil
+//	} else {
+//		res, _ := obj.(map[string]interface{})
+//		return res
+//	}
+//
+//}
+
+//根据代码和前辍key删除多个
+func DelByCodePattern(code, key string) {
+	defer catch()
+
+	conn := RedisPool[code].Get()
+	defer conn.Close()
+	ret, err := conn.Do("KEYS", key)
+	var result []interface{}
+	if nil != err {
+		log.Println("redisutil-GetError", err)
+	} else {
+		result = ret.([]interface{})
+		for k := 0; k < len(result); k++ {
+			conn.Do("DEL", string(result[k].([]uint8)))
+		}
+	}
+}
+
+/**
+func DelByPattern(key string) {
+	defer func() {
+		if r := recover(); r != nil {
+			log.Println("[E]", r)
+			for skip := 1; ; skip++ {
+				_, file, line, ok := runtime.Caller(skip)
+				if !ok {
+					break
+				}
+				go log.Printf("%v,%v\n", file, line)
+			}
+		}
+	}()
+	i := 0
+	for _, v := range RedisPool {
+		conn := v.Get()
+		defer conn.Close()
+		ret, err := conn.Do("KEYS", key)
+		var result []interface{}
+		if nil != err {
+			log.Println("redisutil-GetError", err)
+		} else {
+			result = ret.([]interface{})
+			for k := 0; k < len(result); k++ {
+				delByNum(i, string(result[k].([]uint8)))
+			}
+		}
+		i++
+	}
+
+}
+**/
+//自增计数器
+func Incr(code, key string) int64 {
+	defer catch()
+	conn := RedisPool[code].Get()
+	defer conn.Close()
+	ret, err := conn.Do("INCR", key)
+	if nil != err {
+		log.Println("redisutil-INCR-Error", err)
+	} else {
+		if res, ok := ret.(int64); ok {
+			return res
+		} else {
+			return 0
+		}
+	}
+	return 0
+}
+
+//自减
+func Decrby(code, key string, val int) int64 {
+	defer catch()
+	conn := RedisPool[code].Get()
+	defer conn.Close()
+	ret, err := conn.Do("DECRBY", key, val)
+	if nil != err {
+		log.Println("redisutil-DECR-Error", err)
+	} else {
+		if res, ok := ret.(int64); ok {
+			return res
+		} else {
+			return 0
+		}
+	}
+	return 0
+}
+
+//根据正则去取
+func GetKeysByPattern(code, key string) []interface{} {
+	defer catch()
+	conn := RedisPool[code].Get()
+	defer conn.Close()
+	ret, err := conn.Do("KEYS", key)
+	if nil != err {
+		log.Println("redisutil-GetKeysError", err)
+		return nil
+	} else {
+		res, _ := ret.([]interface{})
+		return res
+	}
+}
+
+//批量取多个key
+func Mget(code string, key []string) []interface{} {
+	defer catch()
+	conn := RedisPool[code].Get()
+	defer conn.Close()
+	interfaceKeys := make([]interface{}, len(key))
+	for n, k := range key {
+		interfaceKeys[n] = k
+	}
+	ret, err := conn.Do("MGET", interfaceKeys...)
+	if nil != err {
+		log.Println("redisutil-MgetError", err)
+		return nil
+	} else {
+		res, _ := ret.([]interface{})
+		return res
+	}
+}
+
+//取出并删除Key
+func Pop(code string, key string) (result interface{}) {
+	defer catch()
+	conn := RedisPool[code].Get()
+	defer conn.Close()
+	ret, err := conn.Do("GET", key)
+	if nil != err {
+		log.Println("redisutil-PopError", err)
+	} else {
+		var ok bool
+		var res []byte
+		if res, ok = ret.([]byte); ok {
+			err = json.Unmarshal(res, &result)
+			if err != nil {
+				log.Println("Poperr", err)
+			}
+		}
+		conn.Do("DEL", key)
+	}
+	return
+}
+
+//list操作
+func LPOP(code, list string) (result interface{}) {
+	defer catch()
+	conn := RedisPool[code].Get()
+	defer conn.Close()
+	ret, err := conn.Do("LPOP", list)
+	if nil != err {
+		log.Println("redisutil-LPopError", err)
+	} else {
+		if res, ok := ret.([]byte); ok {
+			err = json.Unmarshal(res, &result)
+			log.Println(err)
+		}
+	}
+	return
+}
+
+func RPUSH(code, list string, val interface{}) bool {
+	defer catch()
+	conn := RedisPool[code].Get()
+	defer conn.Close()
+	_obj, _ := json.Marshal(val)
+	_, err := conn.Do("RPUSH", list, _obj)
+	if nil != err {
+		log.Println("redisutil-RPUSHError", err)
+		return false
+	}
+	return true
+}
+
+func LLEN(code, list string) int64 {
+	defer catch()
+	conn := RedisPool[code].Get()
+	defer conn.Close()
+	ret, err := conn.Do("LLEN", list)
+	if nil != err {
+		log.Println("redisutil-LLENError", err)
+		return 0
+	}
+	if res, ok := ret.(int64); ok {
+		return res
+	} else {
+		return 0
+	}
+}
+
+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)
+		}
+	}
+}