feat: 优化web
This commit is contained in:
Vendored
+184
@@ -0,0 +1,184 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"giter.top/smart/pkg/config"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
// NewRedis 根据配置创建 Redis 客户端,支持单机、哨兵、集群三种模式。
|
||||
func NewRedis(cfg *config.Config) (redis.UniversalClient) {
|
||||
if cfg == nil {
|
||||
panic("cache: config is nil")
|
||||
}
|
||||
r := cfg.Data.Redis
|
||||
mode := strings.ToLower(strings.TrimSpace(r.Mode))
|
||||
if mode == "" {
|
||||
mode = "standalone"
|
||||
}
|
||||
|
||||
switch mode {
|
||||
case "standalone":
|
||||
addr, err := standaloneAddr(cfg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
opt := &redis.Options{
|
||||
Addr: addr,
|
||||
DB: r.DB,
|
||||
}
|
||||
applyCommonToClient(opt, cfg)
|
||||
return redis.NewClient(opt)
|
||||
|
||||
case "sentinel":
|
||||
if strings.TrimSpace(r.MasterName) == "" {
|
||||
panic("cache: redis sentinel requires master_name")
|
||||
}
|
||||
if len(r.Addrs) == 0 {
|
||||
panic("cache: redis sentinel requires addrs (sentinel 节点列表)")
|
||||
}
|
||||
opt := &redis.FailoverOptions{
|
||||
MasterName: r.MasterName,
|
||||
SentinelAddrs: r.Addrs,
|
||||
DB: r.DB,
|
||||
}
|
||||
applyCommonToFailover(opt, cfg)
|
||||
return redis.NewFailoverClient(opt)
|
||||
|
||||
case "cluster":
|
||||
if len(r.Addrs) == 0 {
|
||||
panic("cache: redis cluster requires addrs")
|
||||
}
|
||||
opt := &redis.ClusterOptions{
|
||||
Addrs: r.Addrs,
|
||||
}
|
||||
applyCommonToCluster(opt, cfg)
|
||||
return redis.NewClusterClient(opt)
|
||||
|
||||
default:
|
||||
panic(fmt.Sprintf("cache: unsupported redis mode %q", r.Mode))
|
||||
}
|
||||
}
|
||||
|
||||
func standaloneAddr(cfg *config.Config) (string, error) {
|
||||
r := cfg.Data.Redis
|
||||
if strings.TrimSpace(r.Addr) != "" {
|
||||
return r.Addr, nil
|
||||
}
|
||||
if len(r.Addrs) > 0 && strings.TrimSpace(r.Addrs[0]) != "" {
|
||||
return r.Addrs[0], nil
|
||||
}
|
||||
return "", errors.New("cache: redis standalone requires addr or addrs[0]")
|
||||
}
|
||||
|
||||
// Ping 用于启动时探测连接是否可用。
|
||||
func Ping(ctx context.Context, c redis.UniversalClient) error {
|
||||
if c == nil {
|
||||
return errors.New("cache: redis client is nil")
|
||||
}
|
||||
return c.Ping(ctx).Err()
|
||||
}
|
||||
|
||||
func applyCommonToClient(opt *redis.Options, cfg *config.Config) {
|
||||
r := cfg.Data.Redis
|
||||
opt.Username = r.Username
|
||||
opt.Password = r.Password
|
||||
if r.PoolSize > 0 {
|
||||
opt.PoolSize = r.PoolSize
|
||||
}
|
||||
if r.MinIdleConns > 0 {
|
||||
opt.MinIdleConns = r.MinIdleConns
|
||||
}
|
||||
if r.MaxRetries != 0 {
|
||||
opt.MaxRetries = r.MaxRetries
|
||||
}
|
||||
if r.RetryDelay > 0 {
|
||||
opt.MinRetryBackoff = r.RetryDelay
|
||||
}
|
||||
if r.RetryMaxDelay > 0 {
|
||||
opt.MaxRetryBackoff = r.RetryMaxDelay
|
||||
}
|
||||
if r.DialTimeout > 0 {
|
||||
opt.DialTimeout = r.DialTimeout
|
||||
}
|
||||
if r.ReadTimeout > 0 {
|
||||
opt.ReadTimeout = r.ReadTimeout
|
||||
}
|
||||
if r.WriteTimeout > 0 {
|
||||
opt.WriteTimeout = r.WriteTimeout
|
||||
}
|
||||
if r.IdleTimeout > 0 {
|
||||
opt.ConnMaxIdleTime = r.IdleTimeout
|
||||
}
|
||||
}
|
||||
|
||||
func applyCommonToFailover(opt *redis.FailoverOptions, cfg *config.Config) {
|
||||
r := cfg.Data.Redis
|
||||
opt.Username = r.Username
|
||||
opt.Password = r.Password
|
||||
if r.PoolSize > 0 {
|
||||
opt.PoolSize = r.PoolSize
|
||||
}
|
||||
if r.MinIdleConns > 0 {
|
||||
opt.MinIdleConns = r.MinIdleConns
|
||||
}
|
||||
if r.MaxRetries != 0 {
|
||||
opt.MaxRetries = r.MaxRetries
|
||||
}
|
||||
if r.RetryDelay > 0 {
|
||||
opt.MinRetryBackoff = r.RetryDelay
|
||||
}
|
||||
if r.RetryMaxDelay > 0 {
|
||||
opt.MaxRetryBackoff = r.RetryMaxDelay
|
||||
}
|
||||
if r.DialTimeout > 0 {
|
||||
opt.DialTimeout = r.DialTimeout
|
||||
}
|
||||
if r.ReadTimeout > 0 {
|
||||
opt.ReadTimeout = r.ReadTimeout
|
||||
}
|
||||
if r.WriteTimeout > 0 {
|
||||
opt.WriteTimeout = r.WriteTimeout
|
||||
}
|
||||
if r.IdleTimeout > 0 {
|
||||
opt.ConnMaxIdleTime = r.IdleTimeout
|
||||
}
|
||||
}
|
||||
|
||||
func applyCommonToCluster(opt *redis.ClusterOptions, cfg *config.Config) {
|
||||
r := cfg.Data.Redis
|
||||
opt.Username = r.Username
|
||||
opt.Password = r.Password
|
||||
if r.PoolSize > 0 {
|
||||
opt.PoolSize = r.PoolSize
|
||||
}
|
||||
if r.MinIdleConns > 0 {
|
||||
opt.MinIdleConns = r.MinIdleConns
|
||||
}
|
||||
if r.MaxRetries != 0 {
|
||||
opt.MaxRetries = r.MaxRetries
|
||||
}
|
||||
if r.RetryDelay > 0 {
|
||||
opt.MinRetryBackoff = r.RetryDelay
|
||||
}
|
||||
if r.RetryMaxDelay > 0 {
|
||||
opt.MaxRetryBackoff = r.RetryMaxDelay
|
||||
}
|
||||
if r.DialTimeout > 0 {
|
||||
opt.DialTimeout = r.DialTimeout
|
||||
}
|
||||
if r.ReadTimeout > 0 {
|
||||
opt.ReadTimeout = r.ReadTimeout
|
||||
}
|
||||
if r.WriteTimeout > 0 {
|
||||
opt.WriteTimeout = r.WriteTimeout
|
||||
}
|
||||
if r.IdleTimeout > 0 {
|
||||
opt.ConnMaxIdleTime = r.IdleTimeout
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user