摘要:把redis加锁方法单独抽离出去放入一个公共方法,暂未做数据类型断言
helper redisLock 文件
package helper
import (
"fmt"
"github.com/garyburd/redigo/redis"
"github.com/prometheus/common/log"
)
type Lock struct {
resource string
token int64
conn redis.Pool
timeout int
}
func (lock *Lock) tryLock() (ok bool, err error) {
_, err = redis.String(lock.conn.Get().Do("SET", lock.key(), lock.token, "EX", int(lock.timeout), "NX"))
if err == redis.ErrNil {
// The lock was not successful, it already exists.
return false, nil
}
if err != nil {
return false, err
}
return true, nil
}
func (lock *Lock) Unlock() (err error) {
_, err = lock.conn.Get().Do("del", lock.key())
return
}
func (lock *Lock) Close() (err error) {
if lock != nil {
lock.conn.Close()
}
return
}
func (lock *Lock) key() string {
return fmt.Sprintf("redislock:%s", lock.resource)
}
func (lock *Lock) AddTimeout(ex_time int64) (ok bool, err error) {
ttl_time, err := redis.Int64(lock.conn.Get().Do("TTL", lock.key()))
fmt.Println(ttl_time)
if err != nil {
log.Fatal("redis get failed:", err)
}
if ttl_time > 0 {
fmt.Println(11)
_, err := redis.String(lock.conn.Get().Do("SET", lock.key(), lock.token, "EX", int(ttl_time+ex_time)))
if err == redis.ErrNil {
return false, nil
}
if err != nil {
return false, err
}
}
return false, nil
}
func (lock *Lock) Get(key string) int64 {
sum, err := redis.Int64(lock.conn.Get().Do("TTL", lock.resource))
if err != nil {
log.Fatal("redis get failed:", err)
}
return sum
}
func TryLockWithTimeout(conn redis.Pool, resource string, token int64, timeout int) (lock *Lock, ok bool, err error) {
lock = &Lock{resource, token, conn, timeout}
ok, err = lock.tryLock()
if !ok || err != nil {
lock = nil
}
return
}
func TryLock(conn redis.Pool, key string, value int64, DefaulTimeout int) (lock *Lock, ok bool, err error) {
return TryLockWithTimeout(conn, key, value, DefaulTimeout)
}
调用(有一些无用import我懒得删了,复制粘贴自行删除)
package main
import (
"apitest/helper"
"context"
"flag"
"fmt"
"github.com/garyburd/redigo/redis"
"github.com/panjf2000/ants"
"github.com/rpcx-ecosystem/rpcx-examples3"
"github.com/smallnest/rpcx/client"
"log"
"net/http"
"time"
)
var redisPool = &redis.Pool{
MaxIdle: 30,
MaxActive: 1000,
IdleTimeout: 30 * time.Second,
Dial: func() (conn redis.Conn, err error) {
//RedisHost := "127.0.0.1:6379" //连接地址
//RedisPassword := "" //连接密码
return redis.Dial("tcp", "127.0.0.1:32769")
},
}
func main() {
//redisPool.Close()
rs := redisPool
//defer rs.Close()
res, ok, err := helper.TryLock(*rs, "key", 0, 12)
//res, ok, err := TryLock(*rs, "key", 0, 12)
if err != nil {
panic(err)
}
if ok {
fmt.Println("加锁成功")
res.Unlock()
} else {
fmt.Println("加锁失败")
}
res.Close()
}