Commit 352e430c96b732e85575685971293aec97c86ced

Authored by 王家文
1 parent dc80cfbc
Exists in master and in 1 other branch dev-wjw

feat✨:redis分布式锁封装

go.mod
... ... @@ -6,6 +6,7 @@ require (
6 6 gitee.com/lxgow/lxconv v0.0.0-20230406110318-b5c75fb5ba53
7 7 github.com/aliyun/aliyun-log-go-sdk v0.1.72
8 8 github.com/astaxie/beego v1.12.3
  9 + github.com/bsm/redislock v0.9.4
9 10 github.com/garyburd/redigo v1.6.4
10 11 github.com/go-sql-driver/mysql v1.7.0
11 12 github.com/gomodule/redigo v2.0.0+incompatible
... ... @@ -19,7 +20,8 @@ require (
19 20 require (
20 21 github.com/beorn7/perks v1.0.1 // indirect
21 22 github.com/cenkalti/backoff v2.2.1+incompatible // indirect
22   - github.com/cespare/xxhash/v2 v2.1.1 // indirect
  23 + github.com/cespare/xxhash/v2 v2.2.0 // indirect
  24 + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
23 25 github.com/go-kit/kit v0.10.0 // indirect
24 26 github.com/go-logfmt/logfmt v0.5.0 // indirect
25 27 github.com/gogo/protobuf v1.3.2 // indirect
... ... @@ -34,6 +36,7 @@ require (
34 36 github.com/prometheus/client_model v0.2.0 // indirect
35 37 github.com/prometheus/common v0.10.0 // indirect
36 38 github.com/prometheus/procfs v0.1.3 // indirect
  39 + github.com/redis/go-redis/v9 v9.0.3 // indirect
37 40 github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 // indirect
38 41 go.uber.org/atomic v1.5.0 // indirect
39 42 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
... ...
go.sum
... ... @@ -68,13 +68,18 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
68 68 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
69 69 github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
70 70 github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
  71 +github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao=
  72 +github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y=
  73 +github.com/bsm/redislock v0.9.4 h1:X/Wse1DPpiQgHbVYRE9zv6m070UcKoOGekgvpNhiSvw=
  74 +github.com/bsm/redislock v0.9.4/go.mod h1:Epf7AJLiSFwLCiZcfi6pWFO/8eAYrYpQXFxEDPoDeAk=
71 75 github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
72 76 github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
73 77 github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
74 78 github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
75 79 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
76   -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
77 80 github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
  81 +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
  82 +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
78 83 github.com/clbanning/mxj/v2 v2.5.5 h1:oT81vUeEiQQ/DcHbzSytRngP6Ky9O+L+0Bw0zSJag9E=
79 84 github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
80 85 github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
... ... @@ -96,6 +101,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
96 101 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
97 102 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
98 103 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
  104 +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
  105 +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
99 106 github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
100 107 github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
101 108 github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
... ... @@ -331,6 +338,8 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
331 338 github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
332 339 github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
333 340 github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
  341 +github.com/redis/go-redis/v9 v9.0.3 h1:+7mmR26M0IvyLxGZUHxu4GiBkJkVDid0Un+j4ScYu4k=
  342 +github.com/redis/go-redis/v9 v9.0.3/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk=
334 343 github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
335 344 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
336 345 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
... ...
service-common/svredis/index.go
... ... @@ -6,51 +6,47 @@ import (
6 6 "apigame/util/utstring"
7 7 "apigame/util/zjson"
8 8 "apigame/util/zredis"
  9 + "apigame/util/zredislock"
9 10 "fmt"
10 11 "github.com/astaxie/beego"
11 12 "github.com/mitchellh/mapstructure"
12 13 )
13 14  
14   -type RedisConfig struct {
15   - Host string `json:"host"`
16   - Port string `json:"port"`
17   - Pwd string `json:"pwd"`
18   - Db string `json:"Db"`
19   - Prefix string `json:"prefix"`
20   -}
21   -
22 15 func Init() bool {
23 16  
  17 + confText, _ := beego.AppConfig.GetSection("redis")
  18 + var confRedis lxredis.MapRedisConfig
  19 + err := mapstructure.Decode(confText, &confRedis)
  20 + if err != nil {
  21 + fmt.Println(" mapstructure.Decode redis Error::" + err.Error())
  22 + return false
  23 + }
24 24 {
25   - //初始化Redis
26   - redisconfig, _ := beego.AppConfig.GetSection("redis")
27   - var mredisconfig lxredis.MapRedisConfig
28   - err := mapstructure.Decode(redisconfig, &mredisconfig)
  25 + // 初始化Redis
  26 + err = lxredis.InitRedis(confRedis)
29 27 if err != nil {
30   - fmt.Println(" mapstructure.Decode Error::" + err.Error())
31   - } else {
32   - err = lxredis.InitRedis(mredisconfig)
33   - if err != nil {
34   - fmt.Println(" lxredis.InitRedis Error::" + err.Error())
35   - return false
36   - }
  28 + fmt.Println(" lxredis.InitRedis Error::" + err.Error())
  29 + return false
37 30 }
38   - fmt.Println(svconst.AppName + " redis init success")
  31 + fmt.Println(svconst.AppName + " lxredis init success")
39 32 }
40 33  
41   - //初始化Redis
42   - confText, _ := beego.AppConfig.GetSection("redis")
43   - var conf RedisConfig
44   - err := mapstructure.Decode(confText, &conf)
45   - if err != nil {
46   - fmt.Println("svredis.Init mapstructure.Decode Error::" + err.Error())
  34 + // 初始化Redis
  35 + {
  36 + zredis.Init(confRedis.Host+":"+confRedis.Port, confRedis.Pwd, utstring.StringToInt(confRedis.Db))
  37 + if !zredis.Check() {
  38 + return false
  39 + }
  40 +
  41 + fmt.Println(svconst.AppName + " zredis init success")
47 42 }
48   - zredis.Init(conf.Host+":"+conf.Port, conf.Pwd, utstring.StringToInt(conf.Db))
49   - if !zredis.Check() {
50   - return false
  43 +
  44 + // 初始化redis锁
  45 + {
  46 + zredislock.Init(confRedis.Host+":"+confRedis.Port, confRedis.Pwd, utstring.StringToInt(confRedis.Db))
  47 + fmt.Println(svconst.AppName + " zredislock init success")
51 48 }
52 49  
53   - fmt.Println(svconst.AppName + " redis init success")
54 50 return true
55 51 }
56 52  
... ...
util/zredis/kv.go
... ... @@ -40,14 +40,14 @@ func Get(key string) (value string, err error) {
40 40 return
41 41 }
42 42  
43   -func SetEx(key, value string, exTime int) (err error) {
  43 +func SetEx(key, value string, ttl int) (err error) {
44 44 conn, errConn := GetConn()
45 45 if errConn != nil {
46 46 return errConn
47 47 }
48 48 defer autoClose(conn)
49 49  
50   - _, err = conn.Do("Set", key, value, "EX", exTime)
  50 + _, err = conn.Do("Set", key, value, "EX", ttl)
51 51 return
52 52 }
53 53  
... ... @@ -71,7 +71,7 @@ func GetInt64(key string) int64 {
71 71 return 0
72 72 }
73 73 defer autoClose(conn)
74   -
  74 +
75 75 value, err := redis.Int64(conn.Do("Get", key))
76 76 if err == nil {
77 77 return value
... ...
util/zredislock/external.go 0 → 100644
... ... @@ -0,0 +1,56 @@
  1 +package zredislock
  2 +
  3 +import (
  4 + "context"
  5 + "fmt"
  6 + "github.com/bsm/redislock"
  7 + "github.com/redis/go-redis/v9"
  8 + "time"
  9 +)
  10 +
  11 +var (
  12 + client *redis.Client
  13 + locker *redislock.Client
  14 +)
  15 +
  16 +type Lock struct {
  17 + Lock *redislock.Lock
  18 + Ctx context.Context
  19 + Err error
  20 +}
  21 +
  22 +func Init(addr, pass string, db int) {
  23 + client = redis.NewClient(&redis.Options{
  24 + Network: "tcp",
  25 + Addr: addr,
  26 + Password: pass,
  27 + DB: db,
  28 + })
  29 +
  30 + locker = redislock.New(client)
  31 +}
  32 +
  33 +// Obtain 获得锁
  34 +func Obtain(key string, ttl time.Duration, opt *redislock.Options) (lock *Lock) {
  35 + lock = &Lock{
  36 + Ctx: context.Background(),
  37 + }
  38 + l, err := locker.Obtain(lock.Ctx, key, ttl, opt)
  39 + if err == redislock.ErrNotObtained {
  40 + fmt.Println("Could not obtain lock!")
  41 + } else if err != nil {
  42 + fmt.Println(err)
  43 + }
  44 + lock.Lock = l
  45 + lock.Err = err
  46 +
  47 + return
  48 +}
  49 +
  50 +// Release 释放锁
  51 +func (l *Lock) Release() {
  52 + err := l.Lock.Release(l.Ctx)
  53 + if err != nil {
  54 + fmt.Println(err)
  55 + }
  56 +}
... ...