本文已参与[新人创作礼]活动,一起开启掘金创作之路。
在golang中调用Redis的lua脚本
使用的redisgo,下面是简单的使用
-
Dial
import (
"encoding/json"
"fmt"
"github.com/garyburd/redigo/redis"
"github.com/spaolacci/murmur3"
"testing"
)
/**
* @Description: redis数据库连接
*/
var (
RD = redis.Pool{
Dial: func() (conn redis.Conn, err error) {
conn, err = redis.Dial("tcp", "127.0.0.1:6379", redis.DialPassword("123456"))
return
}}
Conn =RD.Get()
)
-
Do or Send
//Do让redis客户端执行命令
Conn.Do('GET',key)
//Send写入到客户端输出缓冲区,再调用Flush执行缓冲区的命令
Conn.Send('SET',key,val)
Conn.Send('GET',key)
Conn.Flush()
-
NewScript加载脚本
lua := redis.NewScript(2, string(script))
lua.Do(c,key1,key2)
开始运行一个超卖Demo吧
package main
import (
"fmt"
"github.com/garyburd/redigo/redis"
"io/ioutil"
"math/rand"
"time"
)
/**
* @Description: 生产者负责生产消息
*/
func producer(c redis.Conn, product string) {
defer c.Close()
for {
c.Do("INCR", product)
fmt.Println(product + "+1")
time.Sleep(time.Second)
}
}
/**
* @Description: 消费者负责消费消息
*/
func consumer(c redis.Conn, user string, product string) {
defer c.Close()
script, err := ioutil.ReadFile("./consumer.lua")
if err != nil {
fmt.Println("Script read error", err)
return
}
lua := redis.NewScript(2, string(script))
for {
res, err := lua.Do(c, user, product)
if err != nil {
fmt.Println(err)
return
}
if r, _ := res.(int64); r == 1 {
fmt.Println(user + " buy " + product)
} else if r == 0 {
fmt.Println("Unluckly " + user + "," + product + " is sold out!")
} else {
fmt.Print(user + "/")
}
time.Sleep(time.Millisecond * time.Duration(rand.Intn(10)*100))
}
}
func main() {
pool := &redis.Pool{
// 最大空闲链接
MaxIdle: 10,
// 最大激活链接
MaxActive: 10,
// 最大空闲链接等待时间
IdleTimeout: 10 * time.Second,
Dial: func() (redis.Conn, error) {
c, err := redis.Dial("tcp", "127.0.0.1:6379",redis.DialPassword("123456"))
if err != nil {
fmt.Println("Connect to redis error", err)
}
return c, nil
},
}
//每次开始先清空一下redis
c := pool.Get()
c.Do("FLUSHALL")
c.Close()
go producer(pool.Get(), "apple")
go producer(pool.Get(), "pineapple")
go consumer(pool.Get(), "001", "apple")
go consumer(pool.Get(), "002", "apple")
go consumer(pool.Get(), "002", "pineapple")
time.Sleep(time.Second * 10)
}
运行结果如下:
apple+1
pineapple+1
001 buy apple
Unluckly 002,apple is sold out!
002 buy pineapple
001/002/002/002/apple+1
pineapple+1
001 buy apple
001/002 buy pineapple
002/002/002/001/002/002/pineapple+1
apple+1
002/002 buy apple
Unluckly 001,apple is sold out!
002/002/apple+1
pineapple+1
002/001 buy apple
Unluckly 002,apple is sold out!
002 buy pineapple
pineapple+1
apple+1
001/002/002/001 buy apple
001/Unluckly 002,apple is sold out!
Unluckly 002,apple is sold out!
apple+1
pineapple+1
001/002 buy pineapple
002/002/001 buy apple
pineapple+1
apple+1
002 buy pineapple
002/002/001/002/002/001 buy apple
002/pineapple+1
apple+1
001/002 buy pineapple
002/002/001 buy apple
apple+1
pineapple+1
002/001/001/002 buy apple
002/002/apple+1
pineapple+1
001 buy apple
002/002/Unluckly 002,apple is sold out!
检查一下redis
没有超卖,看起来很Nice