// Package redis 工具包 package redis import ( "context" "sync" "time" "github.com/go-redis/redis" "github.com/runningwater/gohub/pkg/logger" ) // RedisClient Redis 服务 type RedisClient struct { Client *redis.Client Context context.Context } // Ping 测试 Redis 连接 // 通过 Ping 方法测试 Redis 连接是否正常 func (rds *RedisClient) Ping() error { _, err := rds.Client.Ping().Result() return err } // Set 设置 Redis 键值对, 并设置过期时间 func (rds *RedisClient) Set(key string, value any, expiraction time.Duration) bool { if err := rds.Client.Set(key, value, expiraction).Err(); err != nil { logger.ErrorString("Redis", "Set", err.Error()) return false } return true } // Get 获取 Redis 键值对 func (rds *RedisClient) Get(key string) string { val, err := rds.Client.Get(key).Result() if err != nil { logger.ErrorString("Redis", "Get", err.Error()) return "" } return val } // Has 检查 Redis 中是否存在某个键 func (rds *RedisClient) Has(key string) bool { _, err := rds.Client.Get(key).Result() if err != nil { if err == redis.Nil { logger.ErrorString("Redis", "Has", err.Error()) } return false } return true } // Del 删除 Redis 中的键, 支持多个 key 传参 func (rds *RedisClient) Del(keys ...string) bool { if err := rds.Client.Del(keys...).Err(); err != nil { logger.ErrorString("Redis", "Del", err.Error()) return false } return true } // FlushDb 清空 Redis 数据库 func (rds *RedisClient) FlushDb() bool { if err := rds.Client.FlushDB().Err(); err != nil { logger.ErrorString("Redis", "FlushDb", err.Error()) return false } return true } // Increment 当参数只有 1 个时,增加 Redis 中的键值对增加 1 // 当参数有 2 个时,第一个参数为 Key,第二个参数为增加的值 int64 类型 func (rds *RedisClient) Increment(args ...any) bool { switch len(args) { case 1: key := args[0].(string) if err := rds.Client.Incr(key).Err(); err != nil { logger.ErrorString("Redis", "Increment", err.Error()) return false } case 2: key := args[0].(string) value := args[1].(int64) if err := rds.Client.IncrBy(key, value).Err(); err != nil { logger.ErrorString("Redis", "Increment", err.Error()) return false } default: logger.ErrorString("Redis", "Increment", "参数错误, 只能传入 1 或 2 个参数") return false } return true } // Decrement 当参数只有 1 个时,减少 Redis 中的键值对减少 1 // 当参数有 2 个时,第一个参数为 Key,第二个参数为减少的值 int64 类型 func (rds *RedisClient) Decrement(args ...any) bool { switch len(args) { case 1: key := args[0].(string) if err := rds.Client.Decr(key).Err(); err != nil { logger.ErrorString("Redis", "Decrement", err.Error()) return false } case 2: key := args[0].(string) value := args[1].(int64) if err := rds.Client.DecrBy(key, value).Err(); err != nil { logger.ErrorString("Redis", "Decrement", err.Error()) return false } default: logger.ErrorString("Redis", "Decrement", "参数错误, 只能传入 1 或 2 个参数") return false } return true } // func (rds *RedisClient) Reconnect(ctx context.Context) { // for { // err := rds.Ping() // if err == nil { // logger.InfoString("Redis", "Ping", "Redis 连接正常") // return // } // logger.ErrorString("Redis", "Ping", "Redis 连接异常,正在重连...") // // 重新连接 Redis // rds.Client = redis.NewClient(&redis.Options{ // Addr: rds.Client.Options().Addr, // Password: rds.Client.Options().Password, // DB: rds.Client.Options().DB, // }) // select { // case <-ctx.Done(): // logger.InfoString("Redis", "Reconnect", "Redis 重连已取消") // return // case <-time.After(5 * time.Second): // } // } // } // once 确保全局的 Redis 对象只实例一次 var once sync.Once // Redis 全局 Redis, 使用 db 1 var Redis *RedisClient // ConnectRedis 连接 redis 数据库,设置全局 Redis 对象 func ConnectRedis(address, username, password string, db int) { once.Do(func() { Redis = NewClient(address, username, password, db) }) } func NewClient(address, username, password string, db int) *RedisClient { rds := &RedisClient{} rds.Context = context.Background() // 使用 redis 库里的 NewClient 初始化连接 rds.Client = redis.NewClient(&redis.Options{ Addr: address, Password: password, DB: db, }) err := rds.Ping() logger.LogIf(err) // ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) // defer cancel() // rds.Reconnect(ctx) return rds }