大体上的实现思路是声明了一个用来执行redis命令的cmdable结构体,调用该结构体的process方法就可以执行传入的语句
type cmdable struct {
process func(cmd Cmder) error
}
需要传入的cmd是一个Cmder格式的值
type Cmder interface {
Name() string
Args() []interface{}
stringArg(int) string
readReply(rd *proto.Reader) error
setErr(error)
readTimeout() *time.Duration
Err() error
}
而process的实现则是
func (c *baseClient) defaultProcess(cmd Cmder) error {
for attempt := 0; attempt <= c.opt.MaxRetries; attempt++ {
if attempt > 0 {
time.Sleep(c.retryBackoff(attempt))
}
cn, err := c.getConn()
if err != nil {
cmd.setErr(err)
if internal.IsRetryableError(err, true) {
continue
}
return err
}
err = cn.WithWriter(c.opt.WriteTimeout, func(wr *proto.Writer) error {
return writeCmd(wr, cmd)
})
if err != nil {
c.releaseConn(cn, err)
cmd.setErr(err)
if internal.IsRetryableError(err, true) {
continue
}
return err
}
err = cn.WithReader(c.cmdTimeout(cmd), func(rd *proto.Reader) error {
return cmd.readReply(rd)
})
c.releaseConn(cn, err)
if err != nil && internal.IsRetryableError(err, cmd.readTimeout() == nil) {
continue
}
return err
}
return cmd.Err()
}
包含了写入命令和读取反馈,可以将捏好的命令输出到redis进行控制
type RedisClient struct {
addr string
password string
c *redis.Client
}
var redisClient *RedisClient
func InitRedis(cfg *config.AppConfig) error {
opts := redis.Options{
Addr: cfg.RedisAddr, //redis地址
Password: cfg.RedisPassword, //密码
DialTimeout: time.Second * 5, //超时时间
}
client := redis.NewClient(&opts) //创建连接
if err := client.Ping().Err(); err != nil { //心跳测试
return err
}
redisClient = &RedisClient{ //将连接赋值给全局变量
addr: cfg.RedisAddr,
password: cfg.RedisPassword,
c: client,
}
return nil
}
下列所有方法前需加 RedisClient.c. 来调用,返回值全部都是各种格式的cmd,需要使用各种方法来从中取得我们需要的值
方法 | 作用 | 参数 |
---|---|---|
Set | 添加kv | 键 string, 值 interface{}, 过期时间 time.Duration |
Get | 获取值 | 键 string |
Del | 删除kv | 键 …string |
HSet | 给散列添加kv | 散列的键, 散列中的键 string, 值 interface{} |
HGet | 获取散列kv的值 | 散列的键, 散列中的键 string |
FlushAll | 删光 | 无 |
Ping | 心跳验证 | 无 |
Exists | 确认键是否存在 | 键 …string |
Expire | 给key设置过期时间 | 键 string, 过期时间 time.Duration |
Incr | 增加键 | 键 string |
Close | 关闭连接 | 无 |
Watch | 监听键,键出现时执行方法 | 方法 func(*Tx) error, 键 …string |
Decr | 值减一 | 键 string |
方法 | 返回值 |
---|---|
.Err() | err |
.Result() | string,err |
.Int64() | int64,err |
// Get方法封装
func (this *RedisClient) Get(key string) (string, error) {
ret, err := this.c.Get(key).Result()
return ret, err
}
// Set方法封装
func (this *RedisClient) Set(key string, val interface{}, ttl time.Duration) error {
err := this.c.Set(key, val, ttl).Err()
return err
}
// Exists方法封装
func (this *RedisClient) Exists(key string) (bool, error) {
v, err := this.c.Exists(key).Result()
if err != nil {
return false, err
}
return v > 0, nil
}
// Close关闭连接方法封装
func (this *RedisClient) Close() error {
return this.c.Close()
}
上述封装由铭灿提供,感谢杨同志对本文档的鼎力支持