12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- package redis
- import (
- "fmt"
- "github.com/FZambia/sentinel"
- "github.com/gomodule/redigo/redis"
- "github.com/spf13/viper"
- "strings"
- "time"
- )
- // sentinel适配器
- type SentinelAdapter struct {
- pool *redis.Pool
- }
- // 返回sentinel适配器新实例
- func NewSentinelAdapter(nodes []string, masterName string) (IRedisAdapter, error) {
- opts := []redis.DialOption{redis.DialConnectTimeout(5 * time.Second)}
- password := viper.GetString("redis.password")
- if len(strings.TrimSpace(password)) > 0 {
- opts = append(opts, redis.DialPassword(strings.TrimSpace(password)))
- }
- s := &sentinel.Sentinel{
- Addrs: nodes,
- MasterName: masterName,
- Dial: func(addr string) (redis.Conn, error) {
- c, err := redis.Dial("tcp", addr, opts...)
- if err != nil {
- return nil, err
- }
- return c, nil
- },
- }
- maxIdle := viper.GetInt("redis.max_idle")
- maxActive := viper.GetInt("redis.max_active")
- idleTimeout := viper.GetDuration("redis.timeout")
- pool := &redis.Pool{
- MaxIdle: maxIdle,
- MaxActive: maxActive,
- IdleTimeout: idleTimeout,
- Dial: func() (redis.Conn, error) {
- addr, err := s.MasterAddr()
- if err != nil {
- return nil, err
- }
- if conn, err := redis.Dial("tcp", addr, opts...); nil != err {
- return nil, err
- } else {
- return conn, nil
- }
- },
- TestOnBorrow: func(c redis.Conn, t time.Time) error {
- if !sentinel.TestRole(c, "master") {
- return fmt.Errorf("redis sentinel role check failed")
- } else {
- return nil
- }
- },
- }
- return &SentinelAdapter{
- pool: pool,
- }, nil
- }
- // 关闭Redis连接
- func (a *SentinelAdapter) Close() error {
- return a.pool.Close()
- }
- // 执行Redis命令
- func (a *SentinelAdapter) Do(commandName string, args ...interface{}) (interface{}, error) {
- conn := a.pool.Get()
- defer func(conn redis.Conn) {
- _ = conn.Close()
- }(conn)
- if nil == conn {
- return nil, ErrRedisConnNil
- } else {
- return conn.Do(commandName, args...)
- }
- }
- // 返回命令管道操作对象
- func (a *SentinelAdapter) Pipeline() IRedisPipeline {
- return &RedigoPipeline{ // sentinel库兼容redigo库,返回RedigoPipeline即可
- conn: a.pool.Get(),
- }
- }
|