add sentinel new pool

This commit is contained in:
bryanqiu 2023-02-02 19:14:43 +08:00
parent 4bdc9a3e12
commit 2b2e2e8d8c

View File

@ -3,7 +3,9 @@ package sentinel
import (
"errors"
"fmt"
"log"
"net"
"os"
"strings"
"sync"
"time"
@ -54,6 +56,19 @@ import (
// },
// }
// }
type Config struct {
Debug bool `toml:"debug"` //调试开关会在日志打印REDIS语句)
Username string `toml:"username"` //REDIS连接用户名
Password string `toml:"password"` //REDIS连接用户密码
MasterName string `toml:"mastername"` //REDIS主名称一个哨兵集群可管理多个REDIS主从结构
Sentinels string `toml:"sentinels"` //哨兵节点列表,逗号分隔,一般配置三个
Wait bool `toml:"wait"`
MaxIdle int `toml:"max_idle"`
MaxActive int `toml:"max_active"`
IdleTimeout int `toml:"idle_timeout"`
}
type Sentinel struct {
// Addrs is a slice with known Sentinel addresses.
Addrs []string
@ -78,6 +93,60 @@ type Sentinel struct {
addr string
}
func NewPool(cfg Config) *redis.Pool {
var (
masterName = cfg.MasterName
masterPassword = cfg.Password
sntnl = &Sentinel{
Addrs: strings.Split(cfg.Sentinels, ","),
MasterName: masterName,
Dial: func(addr string) (redis.Conn, error) {
timeout := 1000 * time.Millisecond
c, err := redis.DialTimeout("tcp", addr, timeout, timeout, timeout)
if err != nil {
return nil, err
}
return c, nil
},
}
)
return &redis.Pool{
MaxIdle: cfg.MaxIdle,
MaxActive: cfg.MaxActive,
Wait: cfg.Wait,
IdleTimeout: time.Duration(cfg.IdleTimeout) * time.Second,
Dial: func() (redis.Conn, error) {
masterAddr, err := sntnl.MasterAddr()
if err != nil {
return nil, err
}
c, err := redis.Dial("tcp", masterAddr)
if err != nil {
return nil, err
}
okstr, err := redis.String(c.Do("AUTH", masterPassword))
if err != nil {
return nil, fmt.Errorf("redis master AUTH failed: <%s>", err.Error())
} else if okstr != "OK" {
return nil, fmt.Errorf("redis master AUTH failed: <%s>", okstr)
}
if !TestRole(c, "master") {
c.Close()
return nil, fmt.Errorf("%s is not redis master", masterAddr)
}
if cfg.Debug {
c = redis.NewLoggingConn(c, log.New(os.Stdout, "XXXXXXX", log.LstdFlags), "coreredis")
}
return c, nil
},
}
}
// NoSentinelsAvailable is returned when all sentinels in the list are exhausted
// (or none configured), and contains the last error returned by Dial (which
// may be nil)