redisclient.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package redisclient
  2. import (
  3. "app/commons/config"
  4. "app/commons/core"
  5. "context"
  6. "crypto/tls"
  7. "fmt"
  8. "github.com/go-redsync/redsync/v4"
  9. redsyncredis "github.com/go-redsync/redsync/v4/redis"
  10. "github.com/go-redsync/redsync/v4/redis/goredis/v9"
  11. "github.com/redis/go-redis/v9"
  12. "strings"
  13. "time"
  14. )
  15. var (
  16. defaultClient redis.UniversalClient
  17. _redisSync *redsync.Redsync
  18. _redisPool redsyncredis.Pool
  19. )
  20. func DefaultClient() redis.UniversalClient {
  21. if defaultClient == nil {
  22. redisClientInit()
  23. }
  24. return defaultClient
  25. }
  26. func redisSync() *redsync.Redsync {
  27. if _redisSync == nil {
  28. redisClientInit()
  29. }
  30. return _redisSync
  31. }
  32. func redisPool() redsyncredis.Pool {
  33. if _redisPool == nil {
  34. redisClientInit()
  35. }
  36. return _redisPool
  37. }
  38. var exConf *config.Redis
  39. func conf() *config.Redis {
  40. if exConf == nil {
  41. exConf = config.EnvConf().Redis
  42. }
  43. return exConf
  44. }
  45. // LockOptions 定义分布式锁的配置选项
  46. type LockOptions struct {
  47. Expiration int32 // 锁的过期时间(秒)
  48. MaxRetries int // 最大重试次数
  49. RetryDelay time.Duration // 重试间隔
  50. }
  51. // DefaultLockOptions 提供锁配置的默认值
  52. var DefaultLockOptions = LockOptions{
  53. Expiration: 3, // 默认过期时间 3 秒
  54. MaxRetries: 5, // 默认最大重试 5 次
  55. RetryDelay: 200 * time.Millisecond, // 默认重试间隔 200 毫秒
  56. }
  57. func redisClientInit() {
  58. addr := conf().Addr //viper.GetString("redis.addr")
  59. password := conf().Password //viper.GetString("redis.password")
  60. db := conf().Db //viper.GetInt("redis.db")
  61. enabledTls := conf().EnabledTls //viper.GetBool("redis.enabledTls")
  62. if conf().EnabledCluster { //viper.GetBool("redis.enabledCluster")
  63. addrs := conf().Cluster
  64. opts := &redis.ClusterOptions{
  65. Addrs: addrs,
  66. Password: password,
  67. }
  68. if enabledTls {
  69. opts.TLSConfig = &tls.Config{
  70. InsecureSkipVerify: true,
  71. }
  72. }
  73. defaultClient = redis.NewClusterClient(opts)
  74. //if err := defaultClient.Ping(context.TODO()).Err(); err != nil {
  75. // core.Log.Fatal("集群 redis 连接失败, addr: " + strings.Join(addrs, ",") + ", error: " + err.Error())
  76. //}
  77. core.Log.Info("集群 redis 连接成功, addrs: ", strings.Join(addrs, ","))
  78. } else {
  79. opts := &redis.Options{
  80. Addr: addr,
  81. Password: password,
  82. DB: db,
  83. }
  84. if enabledTls {
  85. opts.TLSConfig = &tls.Config{
  86. InsecureSkipVerify: true,
  87. }
  88. }
  89. defaultClient = redis.NewClient(opts)
  90. if err := defaultClient.Ping(context.Background()).Err(); err != nil {
  91. core.Log.Fatal("单体 redis 连接失败, addr: " + addr + ", error: " + err.Error())
  92. }
  93. core.Log.Info(" 单体 redis 连接成功, addr: ", addr)
  94. }
  95. stateInit(defaultClient)
  96. // 初始化 redsync
  97. _redisPool = goredis.NewPool(defaultClient)
  98. _redisSync = redsync.New(_redisPool)
  99. }
  100. var redisKeyNonce = "nonce:%s"
  101. func MustCode(address string) (string, error) {
  102. // 如果存在 nonce 则返回
  103. key := fmt.Sprintf(redisKeyNonce, address)
  104. nonce, err := DefaultClient().Get(context.Background(), key).Result()
  105. if err != nil && err != redis.Nil {
  106. return "", fmt.Errorf("GetNonce error")
  107. }
  108. if nonce != "" {
  109. return nonce, nil
  110. }
  111. // 保存到 redis
  112. result := DefaultClient().Set(context.Background(), key, nonce, time.Duration(0))
  113. if result.Err() != nil {
  114. return "", fmt.Errorf("GetNonce error")
  115. }
  116. return nonce, nil
  117. }