diff --git a/etc/server.conf b/etc/server.conf index 2c2814aa..39c56cf8 100644 --- a/etc/server.conf +++ b/etc/server.conf @@ -116,13 +116,17 @@ BasicAuthPass = "ibex" Timeout = 3000 [Redis] -# address, ip:port +# address, ip:port or ip1:port,ip2:port for cluster and sentinel(SentinelAddrs) Address = "127.0.0.1:6379" # Username = "" # Password = "" # DB = 0 # UseTLS = false # TLSMinVersion = "1.2" +# standalone cluster sentinel +RedisType = "standalone" +# Mastername for sentinel type +# MasterName = "mymaster" [DB] # postgres: host=%s port=%s user=%s dbname=%s password=%s sslmode=%s diff --git a/etc/webapi.conf b/etc/webapi.conf index 0ba8ddd7..3421b3ac 100644 --- a/etc/webapi.conf +++ b/etc/webapi.conf @@ -142,13 +142,17 @@ Phone = "phone_number" Email = "email" [Redis] -# address, ip:port +# address, ip:port or ip1:port,ip2:port for cluster and sentinel(SentinelAddrs) Address = "127.0.0.1:6379" # Username = "" # Password = "" # DB = 0 # UseTLS = false # TLSMinVersion = "1.2" +# standalone cluster sentinel +RedisType = "standalone" +# Mastername for sentinel type +# MasterName = "mymaster" [DB] DSN="root:1234@tcp(127.0.0.1:3306)/n9e_v5?charset=utf8mb4&parseTime=True&loc=Local&allowNativePasswords=true" diff --git a/src/storage/storage.go b/src/storage/storage.go index 99179cac..0d9db4fe 100644 --- a/src/storage/storage.go +++ b/src/storage/storage.go @@ -4,10 +4,13 @@ import ( "context" "fmt" "os" - "github.com/go-redis/redis/v8" - "gorm.io/gorm" + "strings" + "time" + "github.com/didi/nightingale/v5/src/pkg/ormx" "github.com/didi/nightingale/v5/src/pkg/tls" + "github.com/go-redis/redis/v8" + "gorm.io/gorm" ) type RedisConfig struct { @@ -17,6 +20,8 @@ type RedisConfig struct { DB int UseTLS bool tls.ClientConfig + RedisType string + MasterName string } var DB *gorm.DB @@ -29,26 +34,81 @@ func InitDB(cfg ormx.DBConfig) error { return err } -var Redis *redis.Client +var Redis interface { + Del(ctx context.Context, keys ...string) *redis.IntCmd + Get(ctx context.Context, key string) *redis.StringCmd + Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.StatusCmd + HGetAll(ctx context.Context, key string) *redis.StringStringMapCmd + HSet(ctx context.Context, key string, values ...interface{}) *redis.IntCmd + HDel(ctx context.Context, key string, fields ...string) *redis.IntCmd + Close() error + Ping(ctx context.Context) *redis.StatusCmd + Publish(ctx context.Context, channel string, message interface{}) *redis.IntCmd +} func InitRedis(cfg RedisConfig) (func(), error) { - redisOptions := &redis.Options{ - Addr: cfg.Address, - Username: cfg.Username, - Password: cfg.Password, - DB: cfg.DB, - } - - if cfg.UseTLS { - tlsConfig, err := cfg.TLSConfig() - if err != nil { - fmt.Println("failed to init redis tls config:", err) - os.Exit(1) + switch cfg.RedisType { + case "standalone": + redisOptions := &redis.Options{ + Addr: cfg.Address, + Username: cfg.Username, + Password: cfg.Password, + DB: cfg.DB, } - redisOptions.TLSConfig = tlsConfig - } - Redis = redis.NewClient(redisOptions) + if cfg.UseTLS { + tlsConfig, err := cfg.TLSConfig() + if err != nil { + fmt.Println("failed to init redis tls config:", err) + os.Exit(1) + } + redisOptions.TLSConfig = tlsConfig + } + + Redis = redis.NewClient(redisOptions) + + case "cluster": + redisOptions := &redis.ClusterOptions{ + Addrs: strings.Split(cfg.Address, ","), + Username: cfg.Username, + Password: cfg.Password, + } + + if cfg.UseTLS { + tlsConfig, err := cfg.TLSConfig() + if err != nil { + fmt.Println("failed to init redis tls config:", err) + os.Exit(1) + } + redisOptions.TLSConfig = tlsConfig + } + + Redis = redis.NewClusterClient(redisOptions) + + case "sentinel": + redisOptions := &redis.FailoverOptions{ + MasterName: cfg.MasterName, + SentinelAddrs: strings.Split(cfg.Address, ","), + Username: cfg.Username, + Password: cfg.Password, + DB: cfg.DB, + } + + if cfg.UseTLS { + tlsConfig, err := cfg.TLSConfig() + if err != nil { + fmt.Println("failed to init redis tls config:", err) + os.Exit(1) + } + redisOptions.TLSConfig = tlsConfig + } + + Redis = redis.NewFailoverClient(redisOptions) + + default: + fmt.Println("failed to init redis , redis type is illegal:", cfg.RedisType) + os.Exit(1) + } err := Redis.Ping(context.Background()).Err() if err != nil {