github.com/whoyao/protocol@v0.0.0-20230519045905-2d8ace718ca5/redis/redis.go (about) 1 package redis 2 3 import ( 4 "context" 5 "crypto/tls" 6 7 "github.com/pkg/errors" 8 "github.com/redis/go-redis/v9" 9 10 "github.com/whoyao/protocol/logger" 11 ) 12 13 var ErrNotConfigured = errors.New("Redis is not configured") 14 15 type RedisConfig struct { 16 Address string `yaml:"address"` 17 Username string `yaml:"username"` 18 Password string `yaml:"password"` 19 DB int `yaml:"db"` 20 UseTLS bool `yaml:"use_tls"` 21 MasterName string `yaml:"sentinel_master_name"` 22 SentinelUsername string `yaml:"sentinel_username"` 23 SentinelPassword string `yaml:"sentinel_password"` 24 SentinelAddresses []string `yaml:"sentinel_addresses"` 25 ClusterAddresses []string `yaml:"cluster_addresses"` 26 // for clustererd mode only, number of redirects to follow, defaults to 2 27 MaxRedirects *int `yaml:"max_redirects"` 28 } 29 30 func (r *RedisConfig) IsConfigured() bool { 31 if r.Address != "" { 32 return true 33 } 34 if len(r.SentinelAddresses) > 0 { 35 return true 36 } 37 if len(r.ClusterAddresses) > 0 { 38 return true 39 } 40 return false 41 } 42 43 func (r *RedisConfig) GetMaxRedirects() int { 44 if r.MaxRedirects != nil { 45 return *r.MaxRedirects 46 } 47 return 2 48 } 49 50 func GetRedisClient(conf *RedisConfig) (redis.UniversalClient, error) { 51 if conf == nil { 52 return nil, nil 53 } 54 55 if !conf.IsConfigured() { 56 return nil, ErrNotConfigured 57 } 58 59 var rcOptions *redis.UniversalOptions 60 var rc redis.UniversalClient 61 var tlsConfig *tls.Config 62 63 if conf.UseTLS { 64 tlsConfig = &tls.Config{ 65 MinVersion: tls.VersionTLS12, 66 } 67 } 68 69 if len(conf.SentinelAddresses) > 0 { 70 logger.Infow("connecting to redis", "sentinel", true, "addr", conf.SentinelAddresses, "masterName", conf.MasterName) 71 rcOptions = &redis.UniversalOptions{ 72 Addrs: conf.SentinelAddresses, 73 SentinelUsername: conf.SentinelUsername, 74 SentinelPassword: conf.SentinelPassword, 75 MasterName: conf.MasterName, 76 Username: conf.Username, 77 Password: conf.Password, 78 DB: conf.DB, 79 TLSConfig: tlsConfig, 80 } 81 } else if len(conf.ClusterAddresses) > 0 { 82 logger.Infow("connecting to redis", "cluster", true, "addr", conf.ClusterAddresses) 83 rcOptions = &redis.UniversalOptions{ 84 Addrs: conf.ClusterAddresses, 85 Username: conf.Username, 86 Password: conf.Password, 87 DB: conf.DB, 88 TLSConfig: tlsConfig, 89 MaxRedirects: conf.GetMaxRedirects(), 90 } 91 } else { 92 logger.Infow("connecting to redis", "simple", true, "addr", conf.Address) 93 rcOptions = &redis.UniversalOptions{ 94 Addrs: []string{conf.Address}, 95 Username: conf.Username, 96 Password: conf.Password, 97 DB: conf.DB, 98 TLSConfig: tlsConfig, 99 } 100 } 101 rc = redis.NewUniversalClient(rcOptions) 102 103 if err := rc.Ping(context.Background()).Err(); err != nil { 104 err = errors.Wrap(err, "unable to connect to redis") 105 return nil, err 106 } 107 108 return rc, nil 109 }