当前位置:   article > 正文

GoLang封装redigo_golang redigo封装方法

golang redigo封装方法

码字不易,转载请附原链,搬砖繁忙回复不及时见谅,技术交流请加QQ群:909211071

完整最新源码:https://github.com/why444216978/gin-api/blob/master/libraries/redis/redis.go

 

安装redigo扩展

go get -v github.com/gomodule/redigo/redis

 

  1. package redis
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/opentracing/opentracing-go"
  6. "strconv"
  7. "strings"
  8. "time"
  9. "why/config"
  10. "why/log"
  11. "why/util"
  12. "github.com/gomodule/redigo/redis"
  13. )
  14. type RedisDB struct {
  15. pool *redis.Pool
  16. Config *Config
  17. }
  18. var obj map[string]*RedisDB
  19. func Conn(conn string) (db *RedisDB, err error) {
  20. if len(obj) == 0 {
  21. obj = make(map[string]*RedisDB)
  22. }
  23. if obj[conn] != nil {
  24. db = obj[conn]
  25. return
  26. }
  27. fileCfg := config.GetConfigEntrance("redis", conn)
  28. portCfg, err := strconv.Atoi(fileCfg["port"]);
  29. dbCfg, err := strconv.Atoi(fileCfg["db"]);
  30. maxActiveCfg, err := strconv.Atoi(fileCfg["max_active"]);
  31. maxIdleCfg, err := strconv.Atoi(fileCfg["max_idle"]);
  32. logCfg, err := strconv.ParseBool(fileCfg["is_log"])
  33. util.Must(err)
  34. cfg := &Config{
  35. Host: fileCfg["host"],
  36. Port: portCfg,
  37. Password: fileCfg["auth"],
  38. DB: dbCfg,
  39. MaxActive: maxActiveCfg,
  40. MaxIdle: maxIdleCfg,
  41. IsLog: logCfg,
  42. }
  43. db = new(RedisDB)
  44. db.Config = cfg
  45. db.pool = &redis.Pool{
  46. Dial: func() (redis.Conn, error) {
  47. return redis.Dial(
  48. "tcp",
  49. fmt.Sprintf("%s:%d", cfg.Host, cfg.Port),
  50. redis.DialPassword(cfg.Password),
  51. redis.DialDatabase(cfg.DB),
  52. redis.DialConnectTimeout(time.Second*2),
  53. redis.DialReadTimeout(time.Second*2),
  54. redis.DialWriteTimeout(time.Second*2),
  55. )
  56. },
  57. TestOnBorrow: func(c redis.Conn, t time.Time) error {
  58. _, err := c.Do("PING")
  59. return err
  60. },
  61. MaxIdle: cfg.MaxIdle, // 最大的空闲连接数,表示即使没有redis连接时依然可以保持N个空闲的连接,而不被清除,随时处于待命状态
  62. MaxActive: cfg.MaxActive, // 最大的激活连接数,表示同时最多有N个连接 ,为0事表示没有限制
  63. IdleTimeout: time.Second, //最大的空闲连接等待时间,超过此时间后,空闲连接将被关闭
  64. Wait: true, // 当链接数达到最大后是否阻塞,如果不的话,达到最大后返回错误
  65. }
  66. if _, err = db.Do(context.TODO(), "PING"); err != nil {
  67. fmt.Println(err)
  68. err = errorsWrap(err, "ping error")
  69. return
  70. }
  71. obj[conn] = db
  72. return
  73. }
  74. func errorsWrap(err error, msg string) error {
  75. return fmt.Errorf("%s: %w", msg, err)
  76. }
  77. // ConnPool 返回 redis.Pool.
  78. // 除非必要一般不建议用这个函数, 用本库封装好的函数操作数据库.
  79. func (db *RedisDB) ConnPool() *redis.Pool {
  80. return db.pool
  81. }
  82. // Close 释放连接资源.
  83. func (db *RedisDB) Close() error {
  84. if db.pool != nil {
  85. return db.pool.Close()
  86. }
  87. return nil
  88. }
  89. // Do 执行 redis 命令
  90. // NOTE 除非有必要(比如在一个函数内部需要执行多次 redis 操作), 否则请用该函数执行所有的操作, 这样能有效避免忘记释放资源.
  91. func (db *RedisDB) Do(ctx context.Context, commandName string, args ...interface{}) (reply interface{}, err error) {
  92. var (
  93. conn = db.pool.Get()
  94. parent = opentracing.SpanFromContext(ctx)
  95. span opentracing.Span
  96. startAt = time.Now()
  97. endAt time.Time
  98. logFormat = log.LogHeaderFromContext(ctx)
  99. argsStr []string
  100. )
  101. defer conn.Close()
  102. reply, err = conn.Do(commandName, args...)
  103. if db.Config.IsLog == false {
  104. return;
  105. }
  106. if logFormat == nil {
  107. logFormat = log.NewLog()
  108. }
  109. for _, arg := range args {
  110. argsStr = append(argsStr, fmt.Sprint(arg))
  111. }
  112. lastModule := logFormat.Module
  113. defer func() {logFormat.Module = lastModule}()
  114. defer func() {
  115. endAt = time.Now()
  116. logFormat.StartTime = startAt
  117. logFormat.EndTime = endAt
  118. latencyTime := logFormat.EndTime.Sub(logFormat.StartTime).Microseconds()// 执行时间
  119. logFormat.LatencyTime = latencyTime
  120. logFormat.Module = "databus/redis"
  121. if endAt.Sub(startAt) > db.Config.ExecTimeout.Duration {
  122. log.Warnf(logFormat, "redis do:[%s], used: %d milliseconds",
  123. fmt.Sprint(commandName, " ", strings.Join(argsStr, " ")),
  124. endAt.Sub(startAt).Milliseconds())
  125. }
  126. if err != nil {
  127. log.Errorf(logFormat, "redis do:[%s], error: %s",
  128. fmt.Sprint(commandName, " ", strings.Join(argsStr, " ")),
  129. err)
  130. }
  131. }()
  132. if parent == nil {
  133. span = opentracing.StartSpan("redisDo")
  134. } else {
  135. span = opentracing.StartSpan("redisDo", opentracing.ChildOf(parent.Context()))
  136. }
  137. defer span.Finish()
  138. span.SetTag("db.type", "redis")
  139. span.SetTag("db.statement", fmt.Sprint(commandName, " ", strings.Join(argsStr, " ")))
  140. span.SetTag("error", err != nil)
  141. return
  142. }

使用:

  1. package services
  2. import (
  3. "context"
  4. "strconv"
  5. "why/util"
  6. redigo "github.com/gomodule/redigo/redis"
  7. )
  8. const (
  9. location_detail = "location::id_detail:"
  10. location_name = "location::id_name:"
  11. )
  12. func GetLocationDetail(ctx context.Context, id int) string {
  13. db := Conn("location")
  14. data, err := redigo.String( db.Do(ctx, "GET", location_name + strconv.Itoa(id)) )
  15. util.Must(err)
  16. return data
  17. }
  18. func BatchLocationDetail(ctx context.Context, ids []int) []string {
  19. db := Conn("location")
  20. var args []interface{}
  21. for _,v := range ids {
  22. args = append(args, location_detail + strconv.Itoa(v))
  23. }
  24. data, err := redigo.Strings(db.Do(ctx,"MGET", args...))
  25. util.Must(err)
  26. return data
  27. }

config参考:https://blog.csdn.net/why444216978/article/details/103978355

util参考:https://blog.csdn.net/why444216978/article/details/103992579

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/42799
推荐阅读
相关标签
  

闽ICP备14008679号