3 Star 1 Fork 0

NightTC / Gobige

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
RedisAccess.go 5.62 KB
一键复制 编辑 原始数据 按行查看 历史
package redislib
import (
"fmt"
"runtime"
"time"
"gitee.com/night-tc/gobige/logger"
"github.com/gomodule/redigo/redis"
)
var (
//用来设置默认协程数
moduleCap = runtime.NumCPU() * 10
)
// 设置redis地址,带端口
func RedisSetAddr(addr string) redisoptions {
return func(mod *RedisAccess) {
mod.addr = addr
}
}
// 设置redis,auth(进入密码)
func RedisSetAuth(auth string) redisoptions {
return func(mod *RedisAccess) {
mod.auth = auth
}
}
// 设置redis默认的indexdb
func RedisSetIndexDB(indexdb int) redisoptions {
return func(mod *RedisAccess) {
mod.indexdb = indexdb
}
}
// 设置redis最大的空闲连接数,表示即使没有redis连接时依然可以保持N个空闲的连接,而不被清除,随时处于待命状态
func RedisSetMaxIdle(maxidle int) redisoptions {
return func(mod *RedisAccess) {
mod.maxIdle = maxidle
}
}
// 最大的激活连接数,表示同时最多有N个连接 ,为0事表示没有限制
func RedisSetMaxActive(maxactive int) redisoptions {
return func(mod *RedisAccess) {
mod.maxActive = maxactive
}
}
// 最大的空闲连接等待时间,超过此时间后,空闲连接将被关闭(秒)
func RedisSetIdleTimeout(idleTimeout time.Duration) redisoptions {
return func(mod *RedisAccess) {
mod.idleTimeout = idleTimeout * time.Second
}
}
/*
出错重试次数,至少是1
*/
func RedisSetErrRetry(errRetry int) redisoptions {
return func(mod *RedisAccess) {
if errRetry > 1 {
mod.errRetry = errRetry
}
}
}
// 设置错误处理回调
func RedisSeterrFunc(errF errFunc) redisoptions {
return func(mod *RedisAccess) {
mod.errFunc = errF
}
}
type redisoptions func(mod *RedisAccess)
/*
错误处理回调
isend =true 表示重试也失败了,最后一次的回调
isend =false 后面还可以继续重试
返回值true表示如果可以,继续重试;
*/
type errFunc func(err error, isend bool, commandName string, args []interface{}) bool
// RedisAccess redis 管理器
type RedisAccess struct {
DBConobj *redis.Pool //redis连接池
addr string //连接字符串
indexdb int //默认DB号
auth string //连接密码
maxIdle int //最大的空闲连接数,表示即使没有redis连接时依然可以保持N个空闲的连接,而不被清除,随时处于待命状态
maxActive int //最大的激活连接数,表示同时最多有N个连接 ,为0事表示没有限制
idleTimeout time.Duration //最大的空闲连接等待时间,超过此时间后,空闲连接将被关闭(秒)
errRetry int //出错重试次数
errFunc errFunc
}
// NewRedisAccess 生成新的管理器
func NewRedisAccess(opts ...redisoptions) *RedisAccess {
result := &RedisAccess{
addr: "127.0.0.1:6379",
auth: "",
maxIdle: moduleCap / 10,
maxActive: moduleCap,
idleTimeout: 3600 * time.Second,
errRetry: 1,
errFunc: nil,
}
for _, opt := range opts {
opt(result)
}
result.DBConobj = redis.NewPool(result.dial, result.maxIdle)
result.DBConobj.MaxActive = result.maxActive
result.DBConobj.IdleTimeout = result.idleTimeout
result.DBConobj.Wait = true
result.DBConobj.TestOnBorrow = result.testOnBorrow
return result
}
func (access *RedisAccess) dial() (c redis.Conn, err error) {
rawURL := fmt.Sprintf("redis://%s/%d", access.addr, access.indexdb)
if access.auth == "" {
c, err = redis.DialURL(rawURL)
} else {
c, err = redis.DialURL(rawURL, redis.DialPassword(access.auth))
}
// c, err := redis.Dial("tcp", access.addr)
if err != nil {
return nil, err
}
// if access.auth == "" {
// logger.Debug("redis dial.")
// return c, err
// }
// if _, err := c.Do("AUTH", access.auth); err != nil {
// c.Close()
// return nil, err
// }
logger.Info("redis dial.", rawURL)
return c, err
}
func (access *RedisAccess) testOnBorrow(c redis.Conn, t time.Time) error {
// Logger.PDebug("redis testOnBorrow.")
// if time.Since(t) < time.Minute {
// return nil
// }
_, err := c.Do("SELECT", access.indexdb)
return err
}
// GetConn 拿到一个可用的连接,你要在这句之后写上:defer conn.Close()
// 用来在使用完之后把连接放回池子里去
func (access *RedisAccess) GetConn() *RedisHandleModel {
return &RedisHandleModel{
Conn: access.DBConobj.Get(),
access: access,
}
}
// Close 关闭池子,一般只有关服的时候才用到
func (access *RedisAccess) Close() {
access.DBConobj.Close()
// logger.Debug(logger.LogKey_Redis, "redis close.")
}
// RedisHandleModel 自己把reids的一些常用命令写在这里
type RedisHandleModel struct {
redis.Conn
access *RedisAccess
}
func (rd *RedisHandleModel) Dispose() {
rd.Close()
// logger.Debug(logger.LogKey_Redis, "redis Dispose.")
}
// Redis的使用生命周期
func RedisUsing(rd *RedisHandleModel, f func(rd *RedisHandleModel)) {
defer rd.Dispose()
f(rd)
}
func (rd *RedisHandleModel) Do(commandName string, args ...interface{}) (reply interface{}, err error) {
for i := 0; i < rd.access.errRetry; i++ {
reply, err = rd.Conn.Do(commandName, args...)
if err != nil {
//这样写表示默认是会进行重试的
if rd.access.errFunc != nil &&
!rd.access.errFunc(err, true, commandName, args) {
//上面不想继续试了
return
}
} else {
return
}
}
if err != nil && rd.access.errFunc != nil {
rd.access.errFunc(err, true, commandName, args)
}
return
}
func (rd *RedisHandleModel) Close() error {
return rd.Conn.Close()
}
Go
1
https://gitee.com/night-tc/gobige.git
git@gitee.com:night-tc/gobige.git
night-tc
gobige
Gobige
00125336c61c

搜索帮助

53164aa7 5694891 3bd8fe86 5694891