99 lines
2.0 KiB
Go
99 lines
2.0 KiB
Go
|
|
package kv
|
||
|
|
|
||
|
|
import (
|
||
|
|
"errors"
|
||
|
|
"github.com/go-redis/redis"
|
||
|
|
"net"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
var x map[string]*redis.Client = make(map[string]*redis.Client)
|
||
|
|
|
||
|
|
type Config struct {
|
||
|
|
Addrs []string `toml:"addrs" json:"addrs"`
|
||
|
|
Pwd string `toml:"pwd" json:"pwd"`
|
||
|
|
PoolSize int `toml:"pool_size" json:"pool_size"`
|
||
|
|
ReadTimeout int `toml:"read_timeout" json:"read_timeout"`
|
||
|
|
}
|
||
|
|
|
||
|
|
type UnixConfig struct {
|
||
|
|
Addr string `toml:"addr" json:"addr"`
|
||
|
|
PoolSize int `toml:"pool_size" json:"pool_size"`
|
||
|
|
}
|
||
|
|
|
||
|
|
func AddByUnix(name string, c *UnixConfig) error {
|
||
|
|
p := redis.NewClient(&redis.Options{
|
||
|
|
Network: "unix",
|
||
|
|
Addr: c.Addr,
|
||
|
|
PoolSize: c.PoolSize,
|
||
|
|
})
|
||
|
|
|
||
|
|
x[name] = p
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func Add(name string, c *Config) error {
|
||
|
|
p, err := NewRedisClientWithConfig(c)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
x[name] = p
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func GetRedisConn(name string) (*redis.Client, error) {
|
||
|
|
conn, ok := x[name]
|
||
|
|
if ok {
|
||
|
|
return conn, nil
|
||
|
|
}
|
||
|
|
return nil, errors.New("no redis conn")
|
||
|
|
}
|
||
|
|
|
||
|
|
func (c *Config) Parse() (*redis.Options, error) {
|
||
|
|
redisNum := len(c.Addrs)
|
||
|
|
if redisNum < 1 {
|
||
|
|
return nil, errors.New("redis addrs is empty")
|
||
|
|
}
|
||
|
|
ch := make(chan []string, redisNum)
|
||
|
|
for i := 0; i < redisNum; i++ {
|
||
|
|
list := make([]string, redisNum)
|
||
|
|
for j := 0; j < redisNum; j++ {
|
||
|
|
list[j] = c.Addrs[(i+j)%redisNum]
|
||
|
|
}
|
||
|
|
ch <- list
|
||
|
|
}
|
||
|
|
|
||
|
|
if c.ReadTimeout < 1 {
|
||
|
|
c.ReadTimeout = 1
|
||
|
|
}
|
||
|
|
|
||
|
|
options := &redis.Options{
|
||
|
|
Password: c.Pwd,
|
||
|
|
PoolSize: c.PoolSize,
|
||
|
|
ReadTimeout: time.Duration(c.ReadTimeout) * time.Second,
|
||
|
|
WriteTimeout: time.Second,
|
||
|
|
PoolTimeout: time.Second,
|
||
|
|
IdleTimeout: 60 * time.Second,
|
||
|
|
Dialer: func() (net.Conn, error) {
|
||
|
|
list := <-ch
|
||
|
|
ch <- list
|
||
|
|
for _, addr := range list {
|
||
|
|
c, err := net.DialTimeout("tcp", addr, 1000*time.Millisecond)
|
||
|
|
if err == nil {
|
||
|
|
return c, nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return nil, errors.New("all redis down")
|
||
|
|
},
|
||
|
|
}
|
||
|
|
return options, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewRedisClientWithConfig(c *Config) (*redis.Client, error) {
|
||
|
|
options, err := c.Parse()
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
return redis.NewClient(options), nil
|
||
|
|
}
|