Golang如何连接redis哨兵模式,项目案例,模块化客户端

一、go环境说明

D:\dev\demo>go env
set GO111MODULE=on
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\username\AppData\Local\go-build
set GOENV=C:\Users\username\AppData\Roaming\go\env
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\username\go
set GOPRIVATE=
set GOPROXY=https://goproxy.io
set GOROOT=C:\Go
set GOSUMDB=off
set GOTMPDIR=
set GOTOOLDIR=C:\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=D:\dev\demo\go.mod
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=C:\Users\YULIAN~1\AppData\Local\Temp\go-build461750494=/tmp/go-build -gno-record-gcc-switches

D:\dev\v3\ncloud>

二、哨兵客户端
package redis

import (
	"context"
	"fmt"
	"github.com/go-redis/redis/v8"
)


type SentinelConn struct {
	MasterName    string
	SentinelAddrs []string
	Password      string
	DB            int
	Client        *redis.Client
}



func (sentinel *SentinelConn) GetConn() (*redis.Client, error) {
	if sentinel.Client == nil {
		return nil, fmt.Errorf("redis Client connect is nil")
	}
	ctx := context.Background()
	err := sentinel.Client.Ping(ctx).Err()
	if err != nil {
		return nil, err
	}
	return sentinel.Client, nil
}

func (sentinel *SentinelConn) InitSentinelRedis() *redis.Client {
	sf := &redis.FailoverOptions{
		MasterName:    sentinel.MasterName,
		SentinelAddrs: sentinel.SentinelAddrs,
		Password:      sentinel.Password,
		DB:            sentinel.DB,
	}

	return redis.NewFailoverClient(sf)
}

func NewRedisSentinel(mastername, password string, addrs []string, db int) *SentinelConn {
	sentinel := SentinelConn{
		MasterName:    mastername,
		SentinelAddrs: addrs,
		Password:      password,
		DB:            db,
	}
	sentinel.Client = sentinel.InitSentinelRedis()

	return &sentinel

}

三、初始化哨兵客户端
package handler

import (
	"context"
	"fmt"
	"net/http"
	"strings"
	"time"
	"pkg/utils/redis"

)
var (
	MASTER_NAME       = "mymaster"
	SENTINEL_ADDRS    = []string{"192.168.55.219:26379", "192.168.55.227:26379", "192.168.55.230:26379"}
	SENTINEL_PASSWORD = "redis@123.com"
	SENTINEL_DB       = 1
)
var redSentinelConn *redis.SentinelConn

func init() {
	if redSentinelConn == nil {
		redSentinelConn = redis.NewRedisSentinel(MASTER_NAME, SENTINEL_PASSWORD, SENTINEL_ADDRS, SENTINEL_DB)
	}
}
四、使用示例
// field : count,token_count
// ctx := context.Background()

// 登录次数计数器
func getLoginErrorCount(ctx context.Context, uname ,field string) (int, error) {
	count := 0 // 默认是没有登录错误次数
	conn, err := redSentinelConn.GetConn()
	if err != nil {
		return count, err
	}

	bExist, err := conn.HExists(ctx, uname, field).Result()
	if err != nil {
		return count, err
	}
	if bExist == false {
		return count, nil
	} else {
		valmap ,err := conn.HGetAll(ctx, uname).Result()
		if err != nil {
			log.Printf("###### HGetAll err", err)
			return count, nil
		}
		log.Printf("###### HGetAll valmap", valmap)
		val, err := conn.HGet(ctx, uname, field).Int()
		if err != nil {
			log.Printf("###### HMGet hmget err", err)
			return count, nil
		}
		log.Printf("###### HMGet hmget Val", val)
		return val, nil
	}

}


func loginErrorCount(ctx context.Context, uname ,field string) (int, error) {

	conn, err := redSentinelConn.GetConn()
	if err != nil {
		return 0, err
	}
	count, err := getLoginErrorCount(ctx, uname,field)
	log.Printf("###### getDoLoginErrorCount count", count)
	if err != nil {
		log.Printf("doLoginErrorCount err", err)
		return count, nil
	}
	count++
	if count <= 5 {
		err := conn.HSet(ctx, uname, field, count).Err()
		if err != nil {
			log.Printf("redis set error:", err)
		}
	}
	conn.Expire(ctx, uname, 10*time.Minute)

	return count, nil

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值