1 Star 0 Fork 0

h79/goutils

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
adapter.go 4.91 KB
一键复制 编辑 原始数据 按行查看 历史
huqiuyun 提交于 2024-01-04 11:47 . alarm 扩展
package redis
import (
"context"
"crypto/tls"
"fmt"
"gitee.com/h79/goutils/common/result"
"gitee.com/h79/goutils/dao/config"
"gitee.com/h79/goutils/dao/option"
daotls "gitee.com/h79/goutils/dao/util"
"github.com/go-redis/redis/v8"
"go.uber.org/zap"
"strings"
"time"
)
var _ Redis = (*Adapter)(nil)
type Adapter struct {
client *redis.Client
sentinel *redis.SentinelClient
cluster *redis.ClusterClient
name string
}
var DefaultTlsFunc = func(cnf *config.RedisConfig) (*tls.Config, error) {
if strings.EqualFold(cnf.Tls.Key, "false") {
return nil, result.RErrNotSupport
}
if strings.EqualFold(cnf.Tls.Key, "true") {
return &tls.Config{}, nil
}
if strings.EqualFold(cnf.Tls.Key, "skip-verify") ||
strings.EqualFold(cnf.Tls.Key, "preferred") {
return &tls.Config{InsecureSkipVerify: true}, nil
}
cert, rootCertPool, err := daotls.GetCertificate(&cnf.Tls)
if err != nil {
return nil, err
}
return &tls.Config{
RootCAs: rootCertPool,
Certificates: []tls.Certificate{cert},
}, nil
}
func WithTlsOption(f func(cnf *config.RedisConfig) (*tls.Config, error)) option.Option {
return tlsFunc(f)
}
type tlsFunc func(cnf *config.RedisConfig) (*tls.Config, error)
func (t tlsFunc) String() string {
return "redis:tls"
}
func (t tlsFunc) Type() int { return option.TypeRedisTls }
func (t tlsFunc) Value() interface{} { return t }
func tlsFuncExist(opts ...option.Option) tlsFunc {
if r, ok := option.Exist(option.TypeRedisTls, opts...); ok {
return r.Value().(tlsFunc)
}
return nil
}
func UseTls(cnf *config.RedisConfig, opts ...option.Option) (*tls.Config, error) {
fn := tlsFuncExist(opts...)
if fn == nil {
fn = DefaultTlsFunc
}
return fn(cnf)
}
func NewAdapter(name string, cfg *config.RedisConfig, sentinelCfg *config.RedisConfig, clusterCfg *config.RedisConfig, opts ...option.Option) (*Adapter, error) {
cli, err := newClient(cfg)
if err != nil {
return nil, err
}
sentinel, err := newSentinelClient(sentinelCfg)
if err != nil {
zap.L().Warn("Redis: newSentinelClient", zap.Error(err))
}
cluster, err := newClusterClient(clusterCfg)
if err != nil {
zap.L().Warn("Redis: newClusterClient", zap.Error(err))
}
return &Adapter{client: cli, sentinel: sentinel, cluster: cluster, name: name}, nil
}
func newClient(cfg *config.RedisConfig, opts ...option.Option) (*redis.Client, error) {
if len(cfg.Host) == 0 || len(cfg.Host[0]) <= 0 {
return nil, result.RErrParam
}
tlsCfn, _ := UseTls(cfg, opts...)
cli := redis.NewClient(&redis.Options{
Network: "tcp",
Addr: cfg.Host[0],
Username: cfg.User,
Password: cfg.Pwd, // no password set
DB: cfg.DB, // use default DB
DialTimeout: cfg.DialTimeout * time.Second,
ReadTimeout: cfg.ReadTimeout * time.Second,
WriteTimeout: cfg.WriteTimeout * time.Second,
IdleTimeout: cfg.IdleTimeout * time.Minute,
TLSConfig: tlsCfn,
})
ctx := context.Background()
if _, err := cli.Ping(ctx).Result(); err != nil {
daotls.Alarm(result.ErrRdsPingInternal, "", fmt.Sprintf("master redis ping(%s)", cfg.Host), err)
}
return cli, nil
}
func newSentinelClient(cfg *config.RedisConfig, opts ...option.Option) (*redis.SentinelClient, error) {
if len(cfg.Host) == 0 || len(cfg.Host[0]) <= 0 {
return nil, result.RErrParam
}
tlsCfn, _ := UseTls(cfg, opts...)
cli := redis.NewSentinelClient(&redis.Options{
Network: "tcp",
Addr: cfg.Host[0],
Username: cfg.User,
Password: cfg.Pwd, // no password set
DB: cfg.DB, // use default DB
DialTimeout: cfg.DialTimeout * time.Second,
ReadTimeout: cfg.ReadTimeout * time.Second,
WriteTimeout: cfg.WriteTimeout * time.Second,
IdleTimeout: cfg.IdleTimeout * time.Minute,
TLSConfig: tlsCfn,
})
ctx := context.Background()
if _, err := cli.Ping(ctx).Result(); err != nil {
daotls.Alarm(result.ErrRdsPingInternal, "", fmt.Sprintf("sentinel redis ping(%s)", cfg.Host), err)
}
return cli, nil
}
func newClusterClient(cfg *config.RedisConfig, opts ...option.Option) (*redis.ClusterClient, error) {
if len(cfg.Host) == 0 || len(cfg.Host[0]) <= 0 {
return nil, result.RErrParam
}
tlsCfn, _ := UseTls(cfg, opts...)
cli := redis.NewClusterClient(&redis.ClusterOptions{
Addrs: cfg.Host,
Username: cfg.User,
Password: cfg.Pwd, // no password set
DialTimeout: cfg.DialTimeout * time.Second,
ReadTimeout: cfg.ReadTimeout * time.Second,
WriteTimeout: cfg.WriteTimeout * time.Second,
IdleTimeout: cfg.IdleTimeout * time.Minute,
TLSConfig: tlsCfn,
})
ctx := context.Background()
if _, err := cli.Ping(ctx).Result(); err != nil {
daotls.Alarm(result.ErrRdsPingInternal, "", fmt.Sprintf("cluster redis ping(%s)", cfg.Host), err)
}
return cli, nil
}
func (a *Adapter) Rds() *redis.Client {
return a.client
}
func (a *Adapter) Sentinel() *redis.SentinelClient {
return a.sentinel
}
func (a *Adapter) Cluster() *redis.ClusterClient {
return a.cluster
}
func (a *Adapter) Name() string {
return a.name
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/h79/goutils.git
git@gitee.com:h79/goutils.git
h79
goutils
goutils
v1.20.19

搜索帮助