github.com/isyscore/isc-gobase@v1.5.3-0.20231218061332-cbc7451899e9/extend/redis/go-redis.go (about)

     1  package redis
     2  
     3  import (
     4  	goredis "github.com/go-redis/redis/v8"
     5  	"github.com/isyscore/isc-gobase/bean"
     6  	"github.com/isyscore/isc-gobase/config"
     7  	"github.com/isyscore/isc-gobase/constants"
     8  	"github.com/isyscore/isc-gobase/logger"
     9  	baseTime "github.com/isyscore/isc-gobase/time"
    10  	//"github.com/isyscore/isc-gobase/tracing"
    11  	//"github.com/isyscore/isc-gobase/tracing"
    12  	"time"
    13  )
    14  
    15  var RedisHooks []goredis.Hook
    16  
    17  type ConfigError struct {
    18  	ErrMsg string
    19  }
    20  
    21  func (error *ConfigError) Error() string {
    22  	return error.ErrMsg
    23  }
    24  
    25  func init() {
    26  	config.LoadConfig()
    27  
    28  	if config.ExistConfigFile() && config.GetValueBoolDefault("base.redis.enable", false) {
    29  		err := config.GetValueObject("base.redis", &config.RedisCfg)
    30  		if err != nil {
    31  			logger.Warn("读取redis配置异常")
    32  			return
    33  		}
    34  	}
    35  	RedisHooks = []goredis.Hook{}
    36  }
    37  
    38  func NewClient() (goredis.UniversalClient, error) {
    39  	var rdbClient goredis.UniversalClient
    40  	if config.RedisCfg.Sentinel.Master != "" {
    41  		rdbClient = goredis.NewFailoverClient(getSentinelConfig())
    42  	} else if len(config.RedisCfg.Cluster.Addrs) != 0 {
    43  		rdbClient = goredis.NewClusterClient(getClusterConfig())
    44  	} else {
    45  		rdbClient = goredis.NewClient(getStandaloneConfig())
    46  	}
    47  
    48  	for _, hook := range RedisHooks {
    49  		rdbClient.AddHook(hook)
    50  	}
    51  	bean.AddBean(constants.BeanNameRedisPre, &rdbClient)
    52  	return rdbClient, nil
    53  }
    54  
    55  func AddRedisHook(hook goredis.Hook) {
    56  	RedisHooks = append(RedisHooks, hook)
    57  }
    58  
    59  func getStandaloneConfig() *goredis.Options {
    60  	addr := "127.0.0.1:6379"
    61  	if config.RedisCfg.Standalone.Addr != "" {
    62  		addr = config.RedisCfg.Standalone.Addr
    63  	}
    64  
    65  	redisConfig := &goredis.Options{
    66  		Addr: addr,
    67  
    68  		DB:       config.RedisCfg.Standalone.Database,
    69  		Network:  config.RedisCfg.Standalone.Network,
    70  		Username: config.RedisCfg.Username,
    71  		Password: config.RedisCfg.Password,
    72  
    73  		MaxRetries:      config.RedisCfg.MaxRetries,
    74  		MinRetryBackoff: baseTime.NumToTimeDuration(config.RedisCfg.MinRetryBackoff, time.Millisecond),
    75  		MaxRetryBackoff: baseTime.NumToTimeDuration(config.RedisCfg.MaxRetryBackoff, time.Millisecond),
    76  
    77  		DialTimeout:  baseTime.NumToTimeDuration(config.RedisCfg.DialTimeout, time.Millisecond),
    78  		ReadTimeout:  baseTime.NumToTimeDuration(config.RedisCfg.ReadTimeout, time.Millisecond),
    79  		WriteTimeout: baseTime.NumToTimeDuration(config.RedisCfg.WriteTimeout, time.Millisecond),
    80  
    81  		PoolFIFO:           config.RedisCfg.PoolFIFO,
    82  		PoolSize:           config.RedisCfg.PoolSize,
    83  		MinIdleConns:       config.RedisCfg.MinIdleConns,
    84  		MaxConnAge:         baseTime.NumToTimeDuration(config.RedisCfg.MaxConnAge, time.Millisecond),
    85  		PoolTimeout:        baseTime.NumToTimeDuration(config.RedisCfg.PoolTimeout, time.Millisecond),
    86  		IdleTimeout:        baseTime.NumToTimeDuration(config.RedisCfg.IdleTimeout, time.Millisecond),
    87  		IdleCheckFrequency: baseTime.NumToTimeDuration(config.RedisCfg.IdleCheckFrequency, time.Millisecond),
    88  	}
    89  
    90  	// -------- 命令执行失败配置 --------
    91  	if config.GetValueString("base.redis.max-retries") == "" {
    92  		// # 命令执行失败时候,最大重试次数,默认3次,-1(不是0)则不重试
    93  		redisConfig.MaxRetries = 3
    94  	}
    95  
    96  	if config.GetValueString("base.redis.min-retry-backoff") == "" {
    97  		// #(单位毫秒) 命令执行失败时候,每次重试的最小回退时间,默认8毫秒,-1则禁止回退
    98  		redisConfig.MinRetryBackoff = 8*time.Millisecond
    99  	}
   100  
   101  	if config.GetValueString("base.redis.max-retry-backoff") == "" {
   102  		// #(单位毫秒) 命令执行失败时候,每次重试的最小回退时间,默认8毫秒,-1则禁止回退
   103  		redisConfig.MinRetryBackoff = 512*time.Millisecond
   104  	}
   105  
   106  	// -------- 超时配置 --------
   107  	if config.GetValueString("base.redis.dial-timeout") == "" {
   108  		// # (单位毫秒)超时:创建新链接的拨号超时时间,默认15秒
   109  		redisConfig.DialTimeout = 15*time.Second
   110  	}
   111  
   112  	if config.GetValueString("base.redis.read-timeout") == "" {
   113  		// # (单位毫秒)超时:读超时,默认3秒,使用-1,使用-1则表示无超时,0的话是表示默认3秒
   114  		redisConfig.ReadTimeout = 3*time.Second
   115  	}
   116  
   117  	if config.GetValueString("base.redis.write-timeout") == "" {
   118  		// # (单位毫秒)超时:写超时,默认是读超时3秒,使用-1,使用-1则表示无超时,0的话是表示默认3秒
   119  		redisConfig.WriteTimeout = 3*time.Second
   120  	}
   121  
   122  	// -------- 连接池相关配置 --------
   123  	if config.GetValueString("base.redis.pool-fifo") == "" {
   124  		// # 连接池类型:fifo:true;lifo:false;和lifo相比,fifo开销更高
   125  		redisConfig.PoolFIFO = false
   126  	}
   127  
   128  	if config.GetValueString("base.redis.pool-size") == "" {
   129  		// # 最大连接池大小:默认每个cpu核是10个连接,cpu核数可以根据函数runtime.GOMAXPROCS来配置,默认是runtime.NumCpu
   130  		redisConfig.PoolSize = 10
   131  	}
   132  
   133  	if config.GetValueString("base.redis.min-idle-conns") == "" {
   134  		// # 最小空闲连接数
   135  		redisConfig.MinIdleConns = 10
   136  	}
   137  
   138  	if config.GetValueString("base.redis.max-conn-age") == "" {
   139  		// #(单位毫秒) 连接存活时长,默认不关闭
   140  		redisConfig.MaxConnAge = 12*30*24*time.Hour
   141  	}
   142  
   143  	if config.GetValueString("base.redis.pool-timeout") == "" {
   144  		// #(单位毫秒)获取链接池中的链接都在忙,则等待对应的时间,默认读超时+1秒
   145  		redisConfig.PoolTimeout = time.Second
   146  	}
   147  
   148  	if config.GetValueString("base.redis.idle-timeout") == "" {
   149  		// #(单位毫秒)空闲链接时间,超时则关闭,注意:该时间要小于服务端的超时时间,否则会出现拿到的链接失效问题,默认5分钟,-1表示禁用超时检查
   150  		redisConfig.IdleTimeout = 5 * time.Minute
   151  	}
   152  
   153  	if config.GetValueString("base.redis.idle-check-frequency") == "" {
   154  		// #(单位毫秒)空闲链接核查频率,默认1分钟。-1禁止空闲链接核查,即使配置了IdleTime也不行
   155  		redisConfig.IdleCheckFrequency = time.Minute
   156  	}
   157  	return redisConfig
   158  }
   159  
   160  func getSentinelConfig() *goredis.FailoverOptions {
   161  	redisConfig := &goredis.FailoverOptions{
   162  		SentinelAddrs: config.RedisCfg.Sentinel.Addrs,
   163  		MasterName:    config.RedisCfg.Sentinel.Master,
   164  
   165  		DB:               config.RedisCfg.Sentinel.Database,
   166  		Username:         config.RedisCfg.Username,
   167  		Password:         config.RedisCfg.Password,
   168  		SentinelUsername: config.RedisCfg.Sentinel.SentinelUser,
   169  		SentinelPassword: config.RedisCfg.Sentinel.SentinelPassword,
   170  
   171  		MaxRetries:      config.RedisCfg.MaxRetries,
   172  		MinRetryBackoff: baseTime.NumToTimeDuration(config.RedisCfg.MinRetryBackoff, time.Millisecond),
   173  		MaxRetryBackoff: baseTime.NumToTimeDuration(config.RedisCfg.MaxRetryBackoff, time.Millisecond),
   174  
   175  		DialTimeout:  baseTime.NumToTimeDuration(config.RedisCfg.DialTimeout, time.Millisecond),
   176  		ReadTimeout:  baseTime.NumToTimeDuration(config.RedisCfg.ReadTimeout, time.Millisecond),
   177  		WriteTimeout: baseTime.NumToTimeDuration(config.RedisCfg.WriteTimeout, time.Millisecond),
   178  
   179  		PoolFIFO:           config.RedisCfg.PoolFIFO,
   180  		PoolSize:           config.RedisCfg.PoolSize,
   181  		MinIdleConns:       config.RedisCfg.MinIdleConns,
   182  		MaxConnAge:         baseTime.NumToTimeDuration(config.RedisCfg.MaxConnAge, time.Millisecond),
   183  		PoolTimeout:        baseTime.NumToTimeDuration(config.RedisCfg.PoolTimeout, time.Millisecond),
   184  		IdleTimeout:        baseTime.NumToTimeDuration(config.RedisCfg.IdleTimeout, time.Millisecond),
   185  		IdleCheckFrequency: baseTime.NumToTimeDuration(config.RedisCfg.IdleCheckFrequency, time.Millisecond),
   186  	}
   187  
   188  	// -------- 命令执行失败配置 --------
   189  	if config.GetValueString("base.redis.max-retries") == "" {
   190  		// # 命令执行失败时候,最大重试次数,默认3次,-1(不是0)则不重试
   191  		redisConfig.MaxRetries = 3
   192  	}
   193  
   194  	if config.GetValueString("base.redis.min-retry-backoff") == "" {
   195  		// #(单位毫秒) 命令执行失败时候,每次重试的最小回退时间,默认8毫秒,-1则禁止回退
   196  		redisConfig.MinRetryBackoff = 8*time.Millisecond
   197  	}
   198  
   199  	if config.GetValueString("base.redis.max-retry-backoff") == "" {
   200  		// #(单位毫秒) 命令执行失败时候,每次重试的最小回退时间,默认8毫秒,-1则禁止回退
   201  		redisConfig.MinRetryBackoff = 512*time.Millisecond
   202  	}
   203  
   204  	// -------- 超时配置 --------
   205  	if config.GetValueString("base.redis.dial-timeout") == "" {
   206  		// # (单位毫秒)超时:创建新链接的拨号超时时间,默认15秒
   207  		redisConfig.DialTimeout = 15*time.Second
   208  	}
   209  
   210  	if config.GetValueString("base.redis.read-timeout") == "" {
   211  		// # (单位毫秒)超时:读超时,默认3秒,使用-1,使用-1则表示无超时,0的话是表示默认3秒
   212  		redisConfig.ReadTimeout = 3*time.Second
   213  	}
   214  
   215  	if config.GetValueString("base.redis.write-timeout") == "" {
   216  		// # (单位毫秒)超时:写超时,默认是读超时3秒,使用-1,使用-1则表示无超时,0的话是表示默认3秒
   217  		redisConfig.WriteTimeout = 3*time.Second
   218  	}
   219  
   220  	// -------- 连接池相关配置 --------
   221  	if config.GetValueString("base.redis.pool-fifo") == "" {
   222  		// # 连接池类型:fifo:true;lifo:false;和lifo相比,fifo开销更高
   223  		redisConfig.PoolFIFO = false
   224  	}
   225  
   226  	if config.GetValueString("base.redis.pool-size") == "" {
   227  		// # 最大连接池大小:默认每个cpu核是10个连接,cpu核数可以根据函数runtime.GOMAXPROCS来配置,默认是runtime.NumCpu
   228  		redisConfig.PoolSize = 10
   229  	}
   230  
   231  	if config.GetValueString("base.redis.min-idle-conns") == "" {
   232  		// # 最小空闲连接数
   233  		redisConfig.MinIdleConns = 10
   234  	}
   235  
   236  	if config.GetValueString("base.redis.max-conn-age") == "" {
   237  		// #(单位毫秒) 连接存活时长,默认不关闭
   238  		redisConfig.MaxConnAge = 12*30*24*time.Hour
   239  	}
   240  
   241  	if config.GetValueString("base.redis.pool-timeout") == "" {
   242  		// #(单位毫秒)获取链接池中的链接都在忙,则等待对应的时间,默认读超时+1秒
   243  		redisConfig.PoolTimeout = time.Second
   244  	}
   245  
   246  	if config.GetValueString("base.redis.idle-timeout") == "" {
   247  		// #(单位毫秒)空闲链接时间,超时则关闭,注意:该时间要小于服务端的超时时间,否则会出现拿到的链接失效问题,默认5分钟,-1表示禁用超时检查
   248  		redisConfig.IdleTimeout = 5 * time.Minute
   249  	}
   250  
   251  	if config.GetValueString("base.redis.idle-check-frequency") == "" {
   252  		// #(单位毫秒)空闲链接核查频率,默认1分钟。-1禁止空闲链接核查,即使配置了IdleTime也不行
   253  		redisConfig.IdleCheckFrequency = time.Minute
   254  	}
   255  	return redisConfig
   256  }
   257  
   258  func getClusterConfig() *goredis.ClusterOptions {
   259  	if len(config.RedisCfg.Cluster.Addrs) == 0 {
   260  		config.RedisCfg.Cluster.Addrs = []string{"127.0.0.1:6379"}
   261  	}
   262  
   263  	redisConfig := &goredis.ClusterOptions{
   264  		Addrs: config.RedisCfg.Cluster.Addrs,
   265  
   266  		Username: config.RedisCfg.Username,
   267  		Password: config.RedisCfg.Password,
   268  
   269  		MaxRedirects:   config.RedisCfg.Cluster.MaxRedirects,
   270  		ReadOnly:       config.RedisCfg.Cluster.ReadOnly,
   271  		RouteByLatency: config.RedisCfg.Cluster.RouteByLatency,
   272  		RouteRandomly:  config.RedisCfg.Cluster.RouteRandomly,
   273  
   274  		MaxRetries:      config.RedisCfg.MaxRetries,
   275  		MinRetryBackoff: baseTime.NumToTimeDuration(config.RedisCfg.MinRetryBackoff, time.Millisecond),
   276  		MaxRetryBackoff: baseTime.NumToTimeDuration(config.RedisCfg.MaxRetryBackoff, time.Millisecond),
   277  
   278  		DialTimeout:  baseTime.NumToTimeDuration(config.RedisCfg.DialTimeout, time.Millisecond),
   279  		ReadTimeout:  baseTime.NumToTimeDuration(config.RedisCfg.ReadTimeout, time.Millisecond),
   280  		WriteTimeout: baseTime.NumToTimeDuration(config.RedisCfg.WriteTimeout, time.Millisecond),
   281  		PoolFIFO:     config.RedisCfg.PoolFIFO,
   282  		PoolSize:     config.RedisCfg.PoolSize,
   283  		MinIdleConns: config.RedisCfg.MinIdleConns,
   284  
   285  		MaxConnAge:         baseTime.NumToTimeDuration(config.RedisCfg.MaxConnAge, time.Millisecond),
   286  		PoolTimeout:        baseTime.NumToTimeDuration(config.RedisCfg.PoolTimeout, time.Millisecond),
   287  		IdleTimeout:        baseTime.NumToTimeDuration(config.RedisCfg.IdleTimeout, time.Millisecond),
   288  		IdleCheckFrequency: baseTime.NumToTimeDuration(config.RedisCfg.IdleCheckFrequency, time.Millisecond),
   289  	}
   290  
   291  	// -------- 命令执行失败配置 --------
   292  	if config.GetValueString("base.redis.max-retries") == "" {
   293  		// # 命令执行失败时候,最大重试次数,默认3次,-1(不是0)则不重试
   294  		redisConfig.MaxRetries = 3
   295  	}
   296  
   297  	if config.GetValueString("base.redis.min-retry-backoff") == "" {
   298  		// #(单位毫秒) 命令执行失败时候,每次重试的最小回退时间,默认8毫秒,-1则禁止回退
   299  		redisConfig.MinRetryBackoff = 8*time.Millisecond
   300  	}
   301  
   302  	if config.GetValueString("base.redis.max-retry-backoff") == "" {
   303  		// #(单位毫秒) 命令执行失败时候,每次重试的最小回退时间,默认8毫秒,-1则禁止回退
   304  		redisConfig.MinRetryBackoff = 512*time.Millisecond
   305  	}
   306  
   307  	// -------- 超时配置 --------
   308  	if config.GetValueString("base.redis.dial-timeout") == "" {
   309  		// # (单位毫秒)超时:创建新链接的拨号超时时间,默认15秒
   310  		redisConfig.DialTimeout = 15*time.Second
   311  	}
   312  
   313  	if config.GetValueString("base.redis.read-timeout") == "" {
   314  		// # (单位毫秒)超时:读超时,默认3秒,使用-1,使用-1则表示无超时,0的话是表示默认3秒
   315  		redisConfig.ReadTimeout = 3*time.Second
   316  	}
   317  
   318  	if config.GetValueString("base.redis.write-timeout") == "" {
   319  		// # (单位毫秒)超时:写超时,默认是读超时3秒,使用-1,使用-1则表示无超时,0的话是表示默认3秒
   320  		redisConfig.WriteTimeout = 3*time.Second
   321  	}
   322  
   323  	// -------- 连接池相关配置 --------
   324  	if config.GetValueString("base.redis.pool-fifo") == "" {
   325  		// # 连接池类型:fifo:true;lifo:false;和lifo相比,fifo开销更高
   326  		redisConfig.PoolFIFO = false
   327  	}
   328  
   329  	if config.GetValueString("base.redis.pool-size") == "" {
   330  		// # 最大连接池大小:默认每个cpu核是10个连接,cpu核数可以根据函数runtime.GOMAXPROCS来配置,默认是runtime.NumCpu
   331  		redisConfig.PoolSize = 10
   332  	}
   333  
   334  	if config.GetValueString("base.redis.min-idle-conns") == "" {
   335  		// # 最小空闲连接数
   336  		redisConfig.MinIdleConns = 10
   337  	}
   338  
   339  	if config.GetValueString("base.redis.max-conn-age") == "" {
   340  		// #(单位毫秒) 连接存活时长,默认不关闭
   341  		redisConfig.MaxConnAge = 12*30*24*time.Hour
   342  	}
   343  
   344  	if config.GetValueString("base.redis.pool-timeout") == "" {
   345  		// #(单位毫秒)获取链接池中的链接都在忙,则等待对应的时间,默认读超时+1秒
   346  		redisConfig.PoolTimeout = time.Second
   347  	}
   348  
   349  	if config.GetValueString("base.redis.idle-timeout") == "" {
   350  		// #(单位毫秒)空闲链接时间,超时则关闭,注意:该时间要小于服务端的超时时间,否则会出现拿到的链接失效问题,默认5分钟,-1表示禁用超时检查
   351  		redisConfig.IdleTimeout = 5 * time.Minute
   352  	}
   353  
   354  	if config.GetValueString("base.redis.idle-check-frequency") == "" {
   355  		// #(单位毫秒)空闲链接核查频率,默认1分钟。-1禁止空闲链接核查,即使配置了IdleTime也不行
   356  		redisConfig.IdleCheckFrequency = time.Minute
   357  	}
   358  	return redisConfig
   359  }