package util import ( "context" "errors" "fmt" "time" "github.com/redis/go-redis/v9" ) // RedisOptions define struct of redis client config options type RedisOptions struct { Addr string Password string DB int PoolSize int Timeout time.Duration } // RedisOption define a function type for modify RedisOptions type RedisOption func(*RedisOptions) error // WithAddr define func of configure redis addr options func WithAddr(addr string) RedisOption { return func(o *RedisOptions) error { if addr == "" { return errors.New("地址不能为空") } o.Addr = addr return nil } } // WithPassword define func of configure redis password options func WithPassword(password string) RedisOption { return func(o *RedisOptions) error { o.Password = password return nil } } // WithDB define func of configure redis db options func WithDB(db int) RedisOption { return func(o *RedisOptions) error { if db < 0 { return errors.New("数据库编号不能为负数") } o.DB = db return nil } } // WithPoolSize define func of configure pool size options func WithPoolSize(poolSize int) RedisOption { return func(o *RedisOptions) error { if poolSize <= 0 { return errors.New("连接池大小必须大于 0") } o.PoolSize = poolSize return nil } } // WithTimeout define func of configure timeout options func WithTimeout(timeout time.Duration) RedisOption { return func(o *RedisOptions) error { if timeout <= 0 { return errors.New("超时时间必须大于 0") } o.Timeout = timeout return nil } } // NewRedisClient define func of initialize the Redis client func NewRedisClient(opts ...RedisOption) (*redis.Client, error) { // default options options := &RedisOptions{ Addr: "localhost:6379", Password: "", DB: 0, PoolSize: 10, Timeout: 5 * time.Second, } // Apply configuration options from config for _, opt := range opts { if err := opt(options); err != nil { return nil, err } } // create redis client client := redis.NewClient(&redis.Options{ Addr: options.Addr, Password: options.Password, DB: options.DB, PoolSize: options.PoolSize, }) // check if the connection is successful ctx, cancel := context.WithTimeout(context.Background(), options.Timeout) defer cancel() if err := client.Ping(ctx).Err(); err != nil { return nil, fmt.Errorf("can not connect redis:%v", err) } return client, nil }