| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- // Package redis 工具包
- package redis
- import (
- "context"
- "sync"
- "time"
- "github.com/redis/go-redis/v9"
- "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(rds.Context).Result()
- return err
- }
- // Set 设置 Redis 键值对, 并设置过期时间
- func (rds *RedisClient) Set(key string, value any, expiraction time.Duration) bool {
- if err := rds.Client.Set(rds.Context, 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(rds.Context, 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(rds.Context, 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(rds.Context, 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(rds.Context).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(rds.Context, 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(rds.Context, 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(rds.Context, 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(rds.Context, 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
- }
|