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 }