From 7f92e921b4ccf6f92e397c32e7c2d6c6789bba75 Mon Sep 17 00:00:00 2001 From: xtan <38320121+tanxiao1990@users.noreply.github.com> Date: Mon, 30 May 2022 08:36:17 +0800 Subject: [PATCH] =?UTF-8?q?Feat=EF=BC=9A=E5=A2=9E=E5=8A=A0=E5=AF=B9redis?= =?UTF-8?q?=E9=9B=86=E7=BE=A4=E6=A8=A1=E5=BC=8F=E3=80=81=E5=93=A8=E5=85=B5?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E7=9A=84=E6=94=AF=E6=8C=81=20(#965)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 修复go plugin相关错误 * Feat:增加对redis集群模式、哨兵模式的支持 Co-authored-by: tanxiao --- etc/server.conf | 6 ++- etc/webapi.conf | 6 ++- src/storage/storage.go | 96 ++++++++++++++++++++++++++++++++++-------- 3 files changed, 88 insertions(+), 20 deletions(-) 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 {