From 352e430c96b732e85575685971293aec97c86ced Mon Sep 17 00:00:00 2001 From: 王家文 Date: Mon, 22 Apr 2024 18:44:34 +0800 Subject: [PATCH] feat✨:redis分布式锁封装 --- go.mod | 5 ++++- go.sum | 11 ++++++++++- service-common/svredis/index.go | 56 ++++++++++++++++++++++++++------------------------------ util/zredis/kv.go | 6 +++--- util/zredislock/external.go | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 99 insertions(+), 35 deletions(-) create mode 100644 util/zredislock/external.go diff --git a/go.mod b/go.mod index c3764a5..1374aca 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( gitee.com/lxgow/lxconv v0.0.0-20230406110318-b5c75fb5ba53 github.com/aliyun/aliyun-log-go-sdk v0.1.72 github.com/astaxie/beego v1.12.3 + github.com/bsm/redislock v0.9.4 github.com/garyburd/redigo v1.6.4 github.com/go-sql-driver/mysql v1.7.0 github.com/gomodule/redigo v2.0.0+incompatible @@ -19,7 +20,8 @@ require ( require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect - github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/go-kit/kit v0.10.0 // indirect github.com/go-logfmt/logfmt v0.5.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -34,6 +36,7 @@ require ( github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.10.0 // indirect github.com/prometheus/procfs v0.1.3 // indirect + github.com/redis/go-redis/v9 v9.0.3 // indirect github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 // indirect go.uber.org/atomic v1.5.0 // indirect golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect diff --git a/go.sum b/go.sum index d359700..71a17db 100644 --- a/go.sum +++ b/go.sum @@ -68,13 +68,18 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60= +github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao= +github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y= +github.com/bsm/redislock v0.9.4 h1:X/Wse1DPpiQgHbVYRE9zv6m070UcKoOGekgvpNhiSvw= +github.com/bsm/redislock v0.9.4/go.mod h1:Epf7AJLiSFwLCiZcfi6pWFO/8eAYrYpQXFxEDPoDeAk= github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/clbanning/mxj/v2 v2.5.5 h1:oT81vUeEiQQ/DcHbzSytRngP6Ky9O+L+0Bw0zSJag9E= github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= 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 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= 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 github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/redis/go-redis/v9 v9.0.3 h1:+7mmR26M0IvyLxGZUHxu4GiBkJkVDid0Un+j4ScYu4k= +github.com/redis/go-redis/v9 v9.0.3/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= diff --git a/service-common/svredis/index.go b/service-common/svredis/index.go index 01a0697..a0e5dc3 100644 --- a/service-common/svredis/index.go +++ b/service-common/svredis/index.go @@ -6,51 +6,47 @@ import ( "apigame/util/utstring" "apigame/util/zjson" "apigame/util/zredis" + "apigame/util/zredislock" "fmt" "github.com/astaxie/beego" "github.com/mitchellh/mapstructure" ) -type RedisConfig struct { - Host string `json:"host"` - Port string `json:"port"` - Pwd string `json:"pwd"` - Db string `json:"Db"` - Prefix string `json:"prefix"` -} - func Init() bool { + confText, _ := beego.AppConfig.GetSection("redis") + var confRedis lxredis.MapRedisConfig + err := mapstructure.Decode(confText, &confRedis) + if err != nil { + fmt.Println(" mapstructure.Decode redis Error::" + err.Error()) + return false + } { - //初始化Redis - redisconfig, _ := beego.AppConfig.GetSection("redis") - var mredisconfig lxredis.MapRedisConfig - err := mapstructure.Decode(redisconfig, &mredisconfig) + // 初始化Redis + err = lxredis.InitRedis(confRedis) if err != nil { - fmt.Println(" mapstructure.Decode Error::" + err.Error()) - } else { - err = lxredis.InitRedis(mredisconfig) - if err != nil { - fmt.Println(" lxredis.InitRedis Error::" + err.Error()) - return false - } + fmt.Println(" lxredis.InitRedis Error::" + err.Error()) + return false } - fmt.Println(svconst.AppName + " redis init success") + fmt.Println(svconst.AppName + " lxredis init success") } - //初始化Redis - confText, _ := beego.AppConfig.GetSection("redis") - var conf RedisConfig - err := mapstructure.Decode(confText, &conf) - if err != nil { - fmt.Println("svredis.Init mapstructure.Decode Error::" + err.Error()) + // 初始化Redis + { + zredis.Init(confRedis.Host+":"+confRedis.Port, confRedis.Pwd, utstring.StringToInt(confRedis.Db)) + if !zredis.Check() { + return false + } + + fmt.Println(svconst.AppName + " zredis init success") } - zredis.Init(conf.Host+":"+conf.Port, conf.Pwd, utstring.StringToInt(conf.Db)) - if !zredis.Check() { - return false + + // 初始化redis锁 + { + zredislock.Init(confRedis.Host+":"+confRedis.Port, confRedis.Pwd, utstring.StringToInt(confRedis.Db)) + fmt.Println(svconst.AppName + " zredislock init success") } - fmt.Println(svconst.AppName + " redis init success") return true } diff --git a/util/zredis/kv.go b/util/zredis/kv.go index b8da90c..c3878af 100644 --- a/util/zredis/kv.go +++ b/util/zredis/kv.go @@ -40,14 +40,14 @@ func Get(key string) (value string, err error) { return } -func SetEx(key, value string, exTime int) (err error) { +func SetEx(key, value string, ttl int) (err error) { conn, errConn := GetConn() if errConn != nil { return errConn } defer autoClose(conn) - _, err = conn.Do("Set", key, value, "EX", exTime) + _, err = conn.Do("Set", key, value, "EX", ttl) return } @@ -71,7 +71,7 @@ func GetInt64(key string) int64 { return 0 } defer autoClose(conn) - + value, err := redis.Int64(conn.Do("Get", key)) if err == nil { return value diff --git a/util/zredislock/external.go b/util/zredislock/external.go new file mode 100644 index 0000000..e6812ca --- /dev/null +++ b/util/zredislock/external.go @@ -0,0 +1,56 @@ +package zredislock + +import ( + "context" + "fmt" + "github.com/bsm/redislock" + "github.com/redis/go-redis/v9" + "time" +) + +var ( + client *redis.Client + locker *redislock.Client +) + +type Lock struct { + Lock *redislock.Lock + Ctx context.Context + Err error +} + +func Init(addr, pass string, db int) { + client = redis.NewClient(&redis.Options{ + Network: "tcp", + Addr: addr, + Password: pass, + DB: db, + }) + + locker = redislock.New(client) +} + +// Obtain 获得锁 +func Obtain(key string, ttl time.Duration, opt *redislock.Options) (lock *Lock) { + lock = &Lock{ + Ctx: context.Background(), + } + l, err := locker.Obtain(lock.Ctx, key, ttl, opt) + if err == redislock.ErrNotObtained { + fmt.Println("Could not obtain lock!") + } else if err != nil { + fmt.Println(err) + } + lock.Lock = l + lock.Err = err + + return +} + +// Release 释放锁 +func (l *Lock) Release() { + err := l.Lock.Release(l.Ctx) + if err != nil { + fmt.Println(err) + } +} -- libgit2 0.21.0