Commit 352e430c96b732e85575685971293aec97c86ced
1 parent
dc80cfbc
Exists in
master
and in
1 other branch
feat✨:redis分布式锁封装
Showing
5 changed files
with
99 additions
and
35 deletions
Show diff stats
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 | ... | ... |
| ... | ... | @@ -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 | +} | ... | ... |