Compare commits
22 Commits
ec5d33743d
...
master
Author | SHA1 | Date | |
---|---|---|---|
ef3a36f288 | |||
5d1ebcf505 | |||
ac633385b7 | |||
258311256f | |||
a85ebc0203 | |||
ec5f5f0161 | |||
2e05d47fb7 | |||
6f502a5bdd | |||
eec9374d48 | |||
c315db9a8a | |||
9daae92046 | |||
27e193a0ea | |||
e8b63fb863 | |||
f11c0a8216 | |||
63e4412d67 | |||
cbab3ebbc2 | |||
3de0fe084f | |||
0838c037cd | |||
4a8a262d0f | |||
20b30f92a7 | |||
cec7fa76e5 | |||
7e866b3f1f |
@ -9,8 +9,9 @@ package abstract
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.zhangdeman.cn/zhangdeman/consts"
|
||||
"git.zhangdeman.cn/zhangdeman/redis/define"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"github.com/go-redis/redismock/v9"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
@ -20,11 +21,13 @@ import (
|
||||
//
|
||||
// Date : 15:09 2024/6/18
|
||||
type IRedisClient interface {
|
||||
GetRealClient(instanceFlag string) *redis.ClusterClient // 获取客户端连接
|
||||
GetRealClientWithError(instanceFlag string) (*redis.ClusterClient, error) // 获取带error的客户端连接
|
||||
AddClient(instanceFlag string, instanceConfig *redis.ClusterOptions) error // 添加新的客户端连接
|
||||
RemoveClient(instanceFlag string) // 移除一个客户端连接
|
||||
SetLogger(loggerInstance *zap.Logger) // 设置日志实例, 全局生效, 而非针对某一个实例
|
||||
Exec(ctx context.Context, instanceFlag string, command string, args ...any) *define.RedisResult // 执行任意命令
|
||||
SetCommandWhiteList(command []string) // 设置命令的白名单,全局生效, 而非单独针对某一个实例
|
||||
GetRealClient(instanceFlag string) *define.ClientInfo // 获取客户端连接
|
||||
GetRealClientWithError(instanceFlag string) (*define.ClientInfo, error) // 获取带error的客户端连接
|
||||
AddClient(instanceFlag string, instanceConfig *define.Config) error // 添加新的客户端连接
|
||||
RemoveClient(instanceFlag string) // 移除一个客户端连接
|
||||
SetLogger(loggerInstance *zap.Logger, extraLogFieldList []string) // 设置日志实例, 全局生效, 而非针对某一个实例
|
||||
Exec(ctx context.Context, instanceFlag string, command consts.RedisCmd, args ...any) *define.RedisResult // 执行任意命令
|
||||
SetCommandWhiteList(command []consts.RedisCmd) // 设置命令的白名单,全局生效, 而非单独针对某一个实例
|
||||
SetMockMode() // 设置mock模式, 这是单元测试专用的, 生产环境不要使用!!!!!!
|
||||
GetMockInstance() redismock.ClientMock // 数据mock实例
|
||||
}
|
||||
|
@ -1,37 +0,0 @@
|
||||
// Package apply ...
|
||||
//
|
||||
// Description : apply ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2023-02-13 11:24
|
||||
package apply
|
||||
|
||||
import (
|
||||
"git.zhangdeman.cn/zhangdeman/redis"
|
||||
)
|
||||
|
||||
var (
|
||||
// Cache 数据缓存的场景
|
||||
Cache *cache
|
||||
)
|
||||
|
||||
type cache struct {
|
||||
}
|
||||
|
||||
// Set 设置缓存
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 11:28 2023/2/13
|
||||
func (c *cache) Set(ctx *redis.Context, key string, value interface{}) error {
|
||||
var (
|
||||
err error
|
||||
rc *redis.RealClient
|
||||
)
|
||||
|
||||
if rc, err = redis.Client.GetRedisClientWithError(ctx.Flag); nil != err {
|
||||
return err
|
||||
}
|
||||
return rc.Master.Set(nil, key, value, -1).Err()
|
||||
}
|
188
client.go
188
client.go
@ -9,32 +9,41 @@ package redis
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.zhangdeman.cn/zhangdeman/redis/abstract"
|
||||
"git.zhangdeman.cn/zhangdeman/redis/define"
|
||||
"git.zhangdeman.cn/zhangdeman/wrapper"
|
||||
"github.com/pkg/errors"
|
||||
redisClient "github.com/redis/go-redis/v9"
|
||||
"go.uber.org/zap"
|
||||
"git.zhangdeman.cn/zhangdeman/consts"
|
||||
"github.com/go-redis/redismock/v9"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.zhangdeman.cn/zhangdeman/redis/abstract"
|
||||
"git.zhangdeman.cn/zhangdeman/redis/define"
|
||||
wrapperOperate "git.zhangdeman.cn/zhangdeman/wrapper"
|
||||
"github.com/pkg/errors"
|
||||
redisClient "github.com/redis/go-redis/v9"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var Client abstract.IRedisClient
|
||||
var (
|
||||
Client abstract.IRedisClient
|
||||
)
|
||||
|
||||
func init() {
|
||||
Client = &OwnClient{
|
||||
lock: &sync.RWMutex{},
|
||||
instanceTable: make(map[string]*redisClient.ClusterClient),
|
||||
instanceTable: make(map[string]*define.ClientInfo),
|
||||
whiteCommandTable: make(map[string]bool),
|
||||
}
|
||||
}
|
||||
|
||||
type OwnClient struct {
|
||||
lock *sync.RWMutex
|
||||
instanceTable map[string]*redisClient.ClusterClient
|
||||
instanceTable map[string]*define.ClientInfo
|
||||
whiteCommandTable map[string]bool
|
||||
logger *zap.Logger
|
||||
extraLogFieldList []string
|
||||
mockMode bool
|
||||
mockInstance redismock.ClientMock
|
||||
mockClient *redisClient.Client
|
||||
}
|
||||
|
||||
func (o *OwnClient) isAllowCommand(command string) bool {
|
||||
@ -57,27 +66,31 @@ func (o *OwnClient) isAllowCommand(command string) bool {
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 11:05 2024/6/19
|
||||
func (o *OwnClient) Exec(ctx context.Context, instanceFlag string, command string, args ...any) *define.RedisResult {
|
||||
func (o *OwnClient) Exec(ctx context.Context, instanceFlag string, command consts.RedisCmd, args ...any) *define.RedisResult {
|
||||
if nil == ctx {
|
||||
ctx = context.Background()
|
||||
}
|
||||
var (
|
||||
instance *redisClient.ClusterClient
|
||||
instance *define.ClientInfo
|
||||
)
|
||||
|
||||
cmdParamList := []any{
|
||||
command,
|
||||
strings.ToLower(command.String()), // redis 命令不区分大小写, 统一使用小写
|
||||
}
|
||||
argStrList := make([]string, 0)
|
||||
for _, itemArg := range args {
|
||||
argStrList = append(argStrList, wrapper.AnyDataType(itemArg).ToString().Value())
|
||||
argStrList = append(argStrList, wrapperOperate.AnyDataType(itemArg).ToString().Value())
|
||||
cmdParamList = append(cmdParamList, itemArg)
|
||||
}
|
||||
res := &define.RedisResult{
|
||||
StartTime: time.Now().UnixMilli(),
|
||||
FinishTime: 0,
|
||||
UsedTime: 0,
|
||||
Result: "",
|
||||
Command: command,
|
||||
ArgList: argStrList,
|
||||
Err: nil,
|
||||
StartTime: time.Now().UnixMilli(),
|
||||
FinishTime: 0,
|
||||
UsedTime: 0,
|
||||
Result: "",
|
||||
Command: command,
|
||||
ArgList: argStrList,
|
||||
Err: nil,
|
||||
InstanceFlag: instanceFlag,
|
||||
}
|
||||
defer func() {
|
||||
res.FinishTime = time.Now().UnixMilli()
|
||||
@ -86,15 +99,21 @@ func (o *OwnClient) Exec(ctx context.Context, instanceFlag string, command strin
|
||||
// 未注入日志实例
|
||||
return
|
||||
}
|
||||
o.logger.Info(
|
||||
"Redis命令执行记录",
|
||||
logDataList := []zap.Field{
|
||||
zap.Int64("start_time", res.StartTime),
|
||||
zap.Int64("finish_time", res.FinishTime),
|
||||
zap.Int64("used_time", res.UsedTime),
|
||||
zap.String("command", res.Command),
|
||||
zap.String("command", res.Command.String()),
|
||||
zap.String("arg_list", strings.Join(res.ArgList, " ")),
|
||||
zap.String("execute_result", res.Result),
|
||||
zap.Error(res.Err),
|
||||
}
|
||||
for _, item := range o.extraLogFieldList {
|
||||
logDataList = append(logDataList, zap.Any(item, ctx.Value(item)))
|
||||
}
|
||||
o.logger.Info(
|
||||
"Redis命令执行记录",
|
||||
logDataList...,
|
||||
)
|
||||
}()
|
||||
if instance, res.Err = o.GetRealClientWithError(instanceFlag); nil != res.Err {
|
||||
@ -103,11 +122,25 @@ func (o *OwnClient) Exec(ctx context.Context, instanceFlag string, command strin
|
||||
if nil == ctx {
|
||||
ctx = context.Background()
|
||||
}
|
||||
cmdRes := instance.Do(ctx, cmdParamList...)
|
||||
if instance.ReadOnly && o.isWriteCommand(command) {
|
||||
// 只读实例, 尝试执行写命令
|
||||
res.Err = errors.New(instanceFlag + " : instance is read only")
|
||||
return res
|
||||
}
|
||||
if instance.ReadOnly && o.isWriteCommand(command) && instance.MasterClient() == nil {
|
||||
// 写命令, 没有主库连接
|
||||
res.Err = errors.New(instanceFlag + " : instance master client is nil")
|
||||
return res
|
||||
}
|
||||
redisRealClient := instance.MasterClient()
|
||||
if !o.isWriteCommand(command) {
|
||||
redisRealClient = instance.SlaveClient()
|
||||
}
|
||||
cmdRes := redisRealClient.Do(ctx, cmdParamList...)
|
||||
if res.Err = cmdRes.Err(); nil != res.Err {
|
||||
return res
|
||||
}
|
||||
res.Result = cmdRes.String()
|
||||
res.Result = wrapperOperate.AnyDataType(cmdRes.Val()).ToString().Value()
|
||||
return res
|
||||
}
|
||||
|
||||
@ -116,21 +149,21 @@ func (o *OwnClient) Exec(ctx context.Context, instanceFlag string, command strin
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 11:02 2024/6/19
|
||||
func (o *OwnClient) SetCommandWhiteList(commandList []string) {
|
||||
func (o *OwnClient) SetCommandWhiteList(commandList []consts.RedisCmd) {
|
||||
o.lock.Lock()
|
||||
defer o.lock.Unlock()
|
||||
for _, itemCommand := range commandList {
|
||||
o.whiteCommandTable[strings.ToLower(strings.TrimSpace(itemCommand))] = true
|
||||
o.whiteCommandTable[strings.ToLower(strings.TrimSpace(itemCommand.String()))] = true
|
||||
}
|
||||
}
|
||||
|
||||
func (o *OwnClient) GetRealClient(instanceFlag string) *redisClient.ClusterClient {
|
||||
func (o *OwnClient) GetRealClient(instanceFlag string) *define.ClientInfo {
|
||||
o.lock.RLock()
|
||||
defer o.lock.RUnlock()
|
||||
return o.instanceTable[instanceFlag]
|
||||
}
|
||||
|
||||
func (o *OwnClient) GetRealClientWithError(instanceFlag string) (*redisClient.ClusterClient, error) {
|
||||
func (o *OwnClient) GetRealClientWithError(instanceFlag string) (*define.ClientInfo, error) {
|
||||
o.lock.RLock()
|
||||
defer o.lock.RUnlock()
|
||||
instance, exist := o.instanceTable[instanceFlag]
|
||||
@ -140,11 +173,27 @@ func (o *OwnClient) GetRealClientWithError(instanceFlag string) (*redisClient.Cl
|
||||
return instance, nil
|
||||
}
|
||||
|
||||
func (o *OwnClient) AddClient(instanceFlag string, instanceConfig *redisClient.ClusterOptions) error {
|
||||
instance := redisClient.NewClusterClient(instanceConfig)
|
||||
func (o *OwnClient) AddClient(instanceFlag string, instanceConfig *define.Config) error {
|
||||
if nil == instanceConfig.Master && !instanceConfig.ReadOnly {
|
||||
// 不是只读, 则要求 主库配置 和 从库配置都要存在
|
||||
return errors.New(instanceFlag + " : master config is nil")
|
||||
}
|
||||
|
||||
clientInfo := &define.ClientInfo{
|
||||
ReadOnly: instanceConfig.ReadOnly,
|
||||
Master: nil,
|
||||
Slave: nil,
|
||||
}
|
||||
|
||||
if nil != instanceConfig.Master {
|
||||
clientInfo.Master = o.newClient(instanceConfig.Master)
|
||||
}
|
||||
if nil != instanceConfig.Slave {
|
||||
clientInfo.Master = o.newClient(instanceConfig.Slave)
|
||||
}
|
||||
o.lock.Lock()
|
||||
defer o.lock.Unlock()
|
||||
o.instanceTable[instanceFlag] = instance
|
||||
o.instanceTable[instanceFlag] = clientInfo
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -154,6 +203,79 @@ func (o *OwnClient) RemoveClient(instanceFlag string) {
|
||||
delete(o.instanceTable, instanceFlag)
|
||||
}
|
||||
|
||||
func (o *OwnClient) SetLogger(loggerInstance *zap.Logger) {
|
||||
func (o *OwnClient) SetLogger(loggerInstance *zap.Logger, extraLogFieldList []string) {
|
||||
o.logger = loggerInstance
|
||||
o.extraLogFieldList = extraLogFieldList
|
||||
}
|
||||
|
||||
// isWriteCommand 判断是否写命令
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 16:22 2024/10/8
|
||||
func (o *OwnClient) isWriteCommand(command consts.RedisCmd) bool {
|
||||
return wrapperOperate.ArrayType([]consts.RedisCmd{
|
||||
consts.RedisCommandDel,
|
||||
consts.RedisCommandSet,
|
||||
consts.RedisCommandLpush,
|
||||
consts.RedisCommandRpush,
|
||||
consts.RedisCommandMSet,
|
||||
consts.RedisCommandPublish,
|
||||
consts.RedisCommandPsubScribe,
|
||||
}).Has(consts.RedisCmd(strings.ToUpper(command.String()))) >= 0
|
||||
}
|
||||
|
||||
// SetMockMode 启用mock, 非单元测试不要使用!!!!!!!!
|
||||
func (o *OwnClient) SetMockMode() {
|
||||
o.mockMode = true
|
||||
o.mockClient, o.mockInstance = redismock.NewClientMock()
|
||||
}
|
||||
|
||||
// GetMockInstance 获取mock实例
|
||||
func (o *OwnClient) GetMockInstance() redismock.ClientMock {
|
||||
return o.mockInstance
|
||||
}
|
||||
|
||||
// newClient 获取客户端连接
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 16:12 2024/10/8
|
||||
func (o *OwnClient) newClient(instanceConfig *define.Options) *redisClient.Client {
|
||||
if o.mockMode {
|
||||
// mock模式下, 直接返回mock实例
|
||||
return o.mockClient
|
||||
}
|
||||
return redisClient.NewClient(&redisClient.Options{
|
||||
DB: instanceConfig.DB,
|
||||
Addr: instanceConfig.Addr,
|
||||
ClientName: instanceConfig.ClientName,
|
||||
Dialer: nil,
|
||||
OnConnect: func(ctx context.Context, cn *redisClient.Conn) error {
|
||||
return nil
|
||||
},
|
||||
// Protocol: 0,
|
||||
Username: instanceConfig.Username,
|
||||
Password: instanceConfig.Password,
|
||||
// CredentialsProvider: nil,
|
||||
// CredentialsProviderContext: nil,
|
||||
MaxRetries: instanceConfig.MaxRetries,
|
||||
MinRetryBackoff: time.Duration(instanceConfig.MinRetryBackoff) * time.Millisecond,
|
||||
MaxRetryBackoff: time.Duration(instanceConfig.MaxRetryBackoff) * time.Millisecond,
|
||||
DialTimeout: time.Duration(instanceConfig.DialTimeout) * time.Millisecond,
|
||||
ReadTimeout: time.Duration(instanceConfig.ReadTimeout) * time.Millisecond,
|
||||
WriteTimeout: time.Duration(instanceConfig.WriteTimeout) * time.Millisecond,
|
||||
// ContextTimeoutEnabled: instanceConfig.ContextTimeoutEnabled,
|
||||
PoolFIFO: instanceConfig.PoolFIFO,
|
||||
PoolSize: instanceConfig.PoolSize,
|
||||
PoolTimeout: time.Duration(instanceConfig.PoolTimeout) * time.Millisecond,
|
||||
MinIdleConns: instanceConfig.MinIdleConn,
|
||||
// MaxIdleConns: instanceConfig.MaxIdleConn,
|
||||
// MaxActiveConns: instanceConfig.MaxActiveConn,
|
||||
// ConnMaxIdleTime: time.Duration(instanceConfig.ConnMaxIdleTime) * time.Second,
|
||||
// ConnMaxLifetime: time.Duration(instanceConfig.ConnMaxIdleTime) * time.Second,
|
||||
TLSConfig: nil,
|
||||
// DisableIndentity: instanceConfig.DisableIdentity,
|
||||
// IdentitySuffix: instanceConfig.IdentitySuffix,
|
||||
})
|
||||
}
|
||||
|
149
config.go
149
config.go
@ -1,149 +0,0 @@
|
||||
// Package redis ...
|
||||
//
|
||||
// Description : redis ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2022-06-15 11:52
|
||||
package redis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/go-redis/redis/v8"
|
||||
|
||||
"git.zhangdeman.cn/zhangdeman/logger"
|
||||
)
|
||||
|
||||
// FullConfig 完整配置
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 12:23 2022/6/15
|
||||
type FullConfig struct {
|
||||
ExtraFieldList []string `json:"extra_field_list" yaml:"extra_field_list"` // 从上下文抽取的字段信息
|
||||
Logger *logger.InputLogConfig `json:"logger" yaml:"logger"` // 日志配置
|
||||
Master *Config `json:"master" yaml:"master"` // 主节点
|
||||
Slave *Config `json:"slave" yaml:"slave"` // 从节点
|
||||
}
|
||||
|
||||
// Config redis的配置
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 11:52 2022/6/15
|
||||
type Config struct {
|
||||
Network string `json:"network" yaml:"network"` // 连接方式 tcp 或 unix , 默认 tcp
|
||||
Host string `yaml:"host" json:"host"` // 地址
|
||||
Port int `yaml:"port" json:"port"` // 端口
|
||||
|
||||
// Dialer creates new network connection and has priority over
|
||||
// Network and Addr options.
|
||||
// Dialer func(ctx context.Context, network, addr string) (net.Conn, error)
|
||||
|
||||
// Hook that is called when new connection is established.
|
||||
// OnConnect func(ctx context.Context, cn *redis.Conn) error
|
||||
// Use the specified Username to authenticate the current connection
|
||||
// with one of the connections defined in the ACL list when connecting
|
||||
// to a Redis 6.0 instance, or greater, that is using the Redis ACL system.
|
||||
Username string `json:"username" yaml:"username"` // 账号
|
||||
// Optional password. Must match the password specified in the
|
||||
// requirepass server configuration option (if connecting to a Redis 5.0 instance, or lower),
|
||||
// or the User Password when connecting to a Redis 6.0 instance, or greater,
|
||||
// that is using the Redis ACL system.
|
||||
Password string `json:"password" yaml:"password"` // 密码
|
||||
|
||||
// Database to be selected after connecting to the server.
|
||||
DB int `json:"db" yaml:"db"` // 选中的数据库
|
||||
|
||||
// Maximum number of retries before giving up.
|
||||
// Default is 3 retries; -1 (not 0) disables retries.
|
||||
MaxRetries int `json:"max_retries" yaml:"max_retries"` // 最大重试次数, 默认 3 , -1 为不重试
|
||||
// Minimum backoff between each retry.
|
||||
// Default is 8 milliseconds; -1 disables backoff.
|
||||
MinRetryBackoff int64 `json:"min_retry_backoff" yaml:"min_retry_backoff"` // 最小重试的时间间隔, 默认 8ms, -1禁用
|
||||
// Maximum backoff between each retry.
|
||||
// Default is 512 milliseconds; -1 disables backoff.
|
||||
MaxRetryBackoff int `json:"max_retry_backoff" yaml:"max_retry_backoff"` // 最大重试的时间间隔, 默认 512ms, -1禁用
|
||||
|
||||
// Dial timeout for establishing new connections.
|
||||
// Default is 5 seconds.
|
||||
DialTimeout int64 `json:"dial_timeout" yaml:"dial_timeout"` // 建立新连接的超时时间, 默认 5s
|
||||
// Timeout for socket reads. If reached, commands will fail
|
||||
// with a timeout instead of blocking. Use value -1 for no timeout and 0 for default.
|
||||
// Default is 3 seconds.
|
||||
ReadTimeout int64 `json:"read_timeout" yaml:"read_timeout"` // 读取超时时间,默认 3s , -1 不设置超时
|
||||
// Timeout for socket writes. If reached, commands will fail
|
||||
// with a timeout instead of blocking.
|
||||
// Default is ReadTimeout.
|
||||
WriteTimeout int64 `json:"write_timeout" yaml:"write_timeout"` // 写入超时时间, 默认值和 ReadTimeout 配置一致
|
||||
|
||||
// Type of connection pool.
|
||||
// true for FIFO pool, false for LIFO pool.
|
||||
// Note that fifo has higher overhead compared to lifo.
|
||||
PoolFIFO bool `json:"pool_fifo" yaml:"pool_fifo"` // 连接吃采用 FIFO
|
||||
// Maximum number of socket connections.
|
||||
// Default is 10 connections per every available CPU as reported by runtime.GOMAXPROCS.
|
||||
PoolSize int `json:"pool_size" yaml:"pool_size"` // 连接池大小, 默认 runtime.GOMAXPROCS * 10
|
||||
// Minimum number of idle connections which is useful when establishing
|
||||
// new connection is slow.
|
||||
MinIdleConns int `json:"min_idle_conns" yaml:"min_idle_conns"` // 最小的 空闲 连接数数量
|
||||
// Connection age at which client retires (closes) the connection.
|
||||
// Default is to not close aged connections.
|
||||
MaxConnAge int64 `json:"max_conn_age" yaml:"max_conn_age"` // 连接最大的存活时常
|
||||
// Amount of time client waits for connection if all connections
|
||||
// are busy before returning an error.
|
||||
// Default is ReadTimeout + 1 second.
|
||||
PoolTimeout int64 `json:"pool_timeout" yaml:"pool_timeout"` // 连接池无可用连接, 等待的时常, 默认值 ReadTimeout + 1
|
||||
// Amount of time after which client closes idle connections.
|
||||
// Should be less than server's timeout.
|
||||
// Default is 5 minutes. -1 disables idle timeout check.
|
||||
IdleTimeout int64 `json:"idle_timeout" yaml:"idle_timeout"` // 空闲链接的超时时间, 默认 5 分钟 -1 金童
|
||||
// Frequency of idle checks made by idle connections reaper.
|
||||
// Default is 1 minute. -1 disables idle connections reaper,
|
||||
// but idle connections are still discarded by the client
|
||||
// if IdleTimeout is set.
|
||||
IdleCheckFrequency int64 `json:"idle_check_frequency" yaml:"idle_check_frequency"` // 空闲连接检查频率, 默认 1 分钟, -1 禁用, 注意 : 即使禁用,超过 IdleTimeout 时常的连接也不可被读取到
|
||||
}
|
||||
|
||||
// Config2Options 将 自定义的配置文件转为 redis 包需要的配置格式
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 17:37 2022/6/15
|
||||
func Config2Options(cfg *Config) *redis.Options {
|
||||
option := &redis.Options{
|
||||
Network: cfg.Network,
|
||||
Addr: fmt.Sprintf("%v:%v", cfg.Host, cfg.Port),
|
||||
Username: cfg.Username,
|
||||
Password: cfg.Password,
|
||||
DB: cfg.DB,
|
||||
MaxRetries: cfg.MaxRetries,
|
||||
MinRetryBackoff: time.Duration(cfg.MinRetryBackoff) * time.Millisecond,
|
||||
MaxRetryBackoff: time.Duration(cfg.MaxRetryBackoff) * time.Millisecond,
|
||||
DialTimeout: time.Duration(cfg.DialTimeout) * time.Millisecond,
|
||||
ReadTimeout: time.Duration(cfg.ReadTimeout) * time.Millisecond,
|
||||
WriteTimeout: time.Duration(cfg.WriteTimeout) * time.Millisecond,
|
||||
PoolFIFO: cfg.PoolFIFO,
|
||||
PoolSize: cfg.PoolSize,
|
||||
MinIdleConns: cfg.MinIdleConns,
|
||||
MaxConnAge: time.Duration(cfg.MaxConnAge) * time.Millisecond,
|
||||
PoolTimeout: time.Duration(cfg.PoolTimeout) * time.Millisecond,
|
||||
IdleTimeout: time.Duration(cfg.IdleTimeout) * time.Millisecond,
|
||||
IdleCheckFrequency: time.Duration(cfg.IdleCheckFrequency) * time.Millisecond,
|
||||
TLSConfig: nil,
|
||||
Limiter: nil,
|
||||
}
|
||||
if len(option.Network) == 0 {
|
||||
option.Network = NetworkTypeTCP
|
||||
}
|
||||
return option
|
||||
}
|
||||
|
||||
const (
|
||||
// NetworkTypeTCP ...
|
||||
NetworkTypeTCP = "tcp"
|
||||
// NetworkTypeUnix ...
|
||||
NetworkTypeUnix = "unix"
|
||||
)
|
141
context.go
141
context.go
@ -1,141 +0,0 @@
|
||||
// Package redis...
|
||||
//
|
||||
// Description : redis...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2021-02-27 8:22 下午
|
||||
package redis
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.zhangdeman.cn/zhangdeman/easymap"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
const (
|
||||
// 默认的 request_id 字段名
|
||||
defaultRequestIDField = "request_id"
|
||||
// 默认的message
|
||||
defaultMessage = "执行redis命令日志记录"
|
||||
// 耗时字段
|
||||
defaultUsedTimeField = "used_field"
|
||||
// 默认的命令字段
|
||||
defaultCommandField = "command"
|
||||
// 默认记录 redis标识的字段
|
||||
defaultFlagField = "flag"
|
||||
)
|
||||
|
||||
// Context 请求上下文
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 8:25 下午 2021/2/27
|
||||
type Context struct {
|
||||
Flag string // 哪个模块的上下文
|
||||
Ctx context.Context // ctx
|
||||
GinCtx *gin.Context // http 请求绑定的gin.context
|
||||
RequestIDField string // requestID 字段名
|
||||
RequestID string // requestID 此字段有值, 直接使用此值,无值, 去GinCtx 中读取 RequestIDField
|
||||
Extra easymap.EasyMap // 扩展信息
|
||||
}
|
||||
|
||||
// NewContext 生成一个上下文
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 8:26 下午 2021/2/27
|
||||
func NewContext(flag string, of ...SetContextFunc) *Context {
|
||||
ctx := &Context{
|
||||
Flag: flag,
|
||||
Ctx: nil,
|
||||
GinCtx: nil,
|
||||
RequestIDField: "",
|
||||
RequestID: "",
|
||||
Extra: nil,
|
||||
}
|
||||
for _, f := range of {
|
||||
f(ctx)
|
||||
}
|
||||
if nil == ctx.Ctx {
|
||||
ctx.Ctx = context.Background()
|
||||
}
|
||||
if len(ctx.RequestIDField) == 0 {
|
||||
ctx.RequestIDField = defaultRequestIDField
|
||||
}
|
||||
if nil == ctx.Extra {
|
||||
ctx.Extra = easymap.NewNormal()
|
||||
}
|
||||
// requestID 填充
|
||||
if len(ctx.RequestID) == 0 {
|
||||
// 先从 gin 读
|
||||
if nil != ctx.GinCtx {
|
||||
ctx.RequestID = ctx.GinCtx.GetString(ctx.RequestIDField)
|
||||
}
|
||||
// 再从extra读取
|
||||
if len(ctx.RequestID) == 0 {
|
||||
ctx.RequestID, _ = ctx.Extra.GetString(ctx.RequestID)
|
||||
}
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
// SetContextFunc 设置context参数
|
||||
type SetContextFunc func(rc *Context)
|
||||
|
||||
// WithCtx 设置context
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 8:30 下午 2021/2/27
|
||||
func WithCtx(ctx context.Context) SetContextFunc {
|
||||
return func(rc *Context) {
|
||||
rc.Ctx = ctx
|
||||
}
|
||||
}
|
||||
|
||||
// WithGinCtx 设置gin上下文
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 8:34 下午 2021/2/27
|
||||
func WithGinCtx(ginCtx *gin.Context) SetContextFunc {
|
||||
return func(rc *Context) {
|
||||
rc.GinCtx = ginCtx
|
||||
}
|
||||
}
|
||||
|
||||
// WithExtra 设置扩展信息
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 8:36 下午 2021/2/27
|
||||
func WithExtra(extra easymap.EasyMap) SetContextFunc {
|
||||
return func(rc *Context) {
|
||||
rc.Extra = extra
|
||||
}
|
||||
}
|
||||
|
||||
// WithRequestIDField 设置request_id参数名
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 8:41 下午 2021/2/27
|
||||
func WithRequestIDField(requestIDField string) SetContextFunc {
|
||||
return func(rc *Context) {
|
||||
rc.RequestIDField = requestIDField
|
||||
}
|
||||
}
|
||||
|
||||
// WithRequestID ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 8:42 下午 2021/2/27
|
||||
func WithRequestID(requestID string) SetContextFunc {
|
||||
return func(rc *Context) {
|
||||
rc.RequestID = requestID
|
||||
}
|
||||
}
|
@ -7,23 +7,15 @@
|
||||
// Date : 2024-06-18 16:12
|
||||
package define
|
||||
|
||||
type ClusterOptions struct {
|
||||
import redisClient "github.com/redis/go-redis/v9"
|
||||
|
||||
type Options struct {
|
||||
DB int `json:"db" yaml:"db" ini:"db" toml:"db"` // 选择的数据库序号
|
||||
Network string `json:"network" yaml:"network" ini:"network" toml:"network"` // 网络连接方式
|
||||
// A seed list of host:port addresses of cluster nodes.
|
||||
Addrs []string `json:"addrs" yaml:"addrs" ini:"addrs" toml:"addrs"` // 集群IP列表
|
||||
Addr string `json:"addr" yaml:"addr" ini:"addr" toml:"addr"` // 集群IP列表
|
||||
// ClientName will execute the `CLIENT SETNAME ClientName` command for each conn.
|
||||
ClientName string `json:"client_name" yaml:"client_name" ini:"client_name" toml:"client_name"` // 集群名称
|
||||
// The maximum number of retries before giving up. Command is retried
|
||||
// on network errors and MOVED/ASK redirects.
|
||||
// Default is 3 retries.
|
||||
MaxRedirects int `json:"max_redirects" yaml:"max_redirects" ini:"max_redirects" toml:"max_redirects"` // 最大重试次数
|
||||
// Enables read-only commands on slave nodes.
|
||||
ReadOnly bool `json:"read_only" yaml:"read_only" ini:"read_only" toml:"read_only"` // 只读
|
||||
// Allows routing read-only commands to the closest master or slave node.
|
||||
// It automatically enables ReadOnly.
|
||||
RouteByLatency bool `json:"route_by_latency" yaml:"route_by_latency" ini:"route_by_latency" toml:"route_by_latency"`
|
||||
// Allows routing read-only commands to the random master or slave node.
|
||||
// It automatically enables ReadOnly.
|
||||
RouteRandomly bool `json:"route_randomly" yaml:"route_randomly" ini:"route_randomly" toml:"route_randomly"`
|
||||
|
||||
Protocol int
|
||||
Username string `json:"username" yaml:"username" ini:"username" toml:"username"`
|
||||
@ -51,3 +43,36 @@ type ClusterOptions struct {
|
||||
|
||||
IdentitySuffix string `json:"identity_suffix" yaml:"identity_suffix" ini:"identity_suffix" toml:"identity_suffix"` // Add suffix to client name. Default is empty.
|
||||
}
|
||||
|
||||
// Config 数据库连接配置
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 15:59 2024/10/8
|
||||
type Config struct {
|
||||
ReadOnly bool `json:"readonly" yaml:"readonly" ini:"readonly" toml:"readonly"`
|
||||
Master *Options `json:"master" yaml:"master" ini:"master" toml:"master"` // 主库配置
|
||||
Slave *Options `json:"slave" yaml:"slave" ini:"slave" toml:"slave"` // 主库配置
|
||||
}
|
||||
|
||||
// ClientInfo 客户端连接信息
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 16:06 2024/10/8
|
||||
type ClientInfo struct {
|
||||
ReadOnly bool // 是否只读
|
||||
Master *redisClient.Client // 主库连接
|
||||
Slave *redisClient.Client // 从库连接
|
||||
}
|
||||
|
||||
func (cf *ClientInfo) MasterClient() *redisClient.Client {
|
||||
return cf.Master
|
||||
}
|
||||
|
||||
func (cf *ClientInfo) SlaveClient() *redisClient.Client {
|
||||
if nil != cf.Slave {
|
||||
return cf.Slave
|
||||
}
|
||||
return cf.Master
|
||||
}
|
||||
|
@ -7,18 +7,20 @@
|
||||
// Date : 2024-06-19 10:49
|
||||
package define
|
||||
|
||||
import "git.zhangdeman.cn/zhangdeman/consts"
|
||||
|
||||
// RedisResult redis名玲玲执行结果
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 10:50 2024/6/19
|
||||
type RedisResult struct {
|
||||
InstanceFlag string `json:"instance_flag"` // 实例标识
|
||||
StartTime int64 `json:"start_time"` // 开始执行时间, 单位 : ms
|
||||
FinishTime int64 `json:"finish_time"` // 完成执行时间, 单位 : ms
|
||||
UsedTime int64 `json:"used_time"` // 执行耗时, 单位 : ms
|
||||
Result string `json:"result"` // 执行结果
|
||||
Command string `json:"command"` // 执行的命令
|
||||
ArgList []string `json:"arg_list"` // 参数列表
|
||||
Err error `json:"-"` // 失败信息
|
||||
InstanceFlag string `json:"instance_flag"` // 实例标识
|
||||
StartTime int64 `json:"start_time"` // 开始执行时间, 单位 : ms
|
||||
FinishTime int64 `json:"finish_time"` // 完成执行时间, 单位 : ms
|
||||
UsedTime int64 `json:"used_time"` // 执行耗时, 单位 : ms
|
||||
Result string `json:"result"` // 执行结果
|
||||
Command consts.RedisCmd `json:"command"` // 执行的命令
|
||||
ArgList []string `json:"arg_list"` // 参数列表
|
||||
Err error `json:"-"` // 失败信息
|
||||
}
|
||||
|
54
go.mod
54
go.mod
@ -1,60 +1,34 @@
|
||||
module git.zhangdeman.cn/zhangdeman/redis
|
||||
|
||||
go 1.21
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.21.5
|
||||
toolchain go1.24.2
|
||||
|
||||
require (
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240617073616-39e82fd033ed
|
||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211
|
||||
git.zhangdeman.cn/zhangdeman/logger v0.0.0-20240308024848-54993a0ed4a6
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240618035451-8d48a6bd39dd
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250420101447-0b570213d5c7
|
||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
github.com/go-redis/redis/v8 v8.11.5
|
||||
github.com/go-redis/redis_rate/v9 v9.1.2
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250321102712-1cbfbe959740
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/redis/go-redis/v9 v9.7.3
|
||||
go.uber.org/zap v1.27.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.4.0 // indirect
|
||||
github.com/bytedance/sonic v1.11.8 // indirect
|
||||
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4 // indirect
|
||||
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 // indirect
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd // indirect
|
||||
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
||||
github.com/chenzhuoyu/iasm v0.9.1 // indirect
|
||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.4 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.22.0 // indirect
|
||||
github.com/goccy/go-json v0.10.3 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible // indirect
|
||||
github.com/lestrrat-go/strftime v1.0.6 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/go-redis/redismock/v9 v9.2.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mozillazg/go-pinyin v0.20.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/redis/go-redis/v9 v9.5.3 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
github.com/tidwall/gjson v1.18.0 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/crypto v0.24.0 // indirect
|
||||
golang.org/x/net v0.26.0 // indirect
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
)
|
||||
|
277
go.sum
277
go.sum
@ -1,256 +1,101 @@
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20230815040024-2b12dd51d19b h1:C7KftnLh7dOqzNRs5dn/9yqMDvuqMn5RCglvV6bY758=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20230815040024-2b12dd51d19b/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240104123641-b3f23974e5d6 h1:ytpXTP3oxp480BAZQoOzqlBP4XP73NcpMplZ1/fA1lQ=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240104123641-b3f23974e5d6/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240617073616-39e82fd033ed h1:BGv+y6ZdtkxI4HeSIHun0QRrIzjLnUht0bKdyO2t6n4=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240617073616-39e82fd033ed/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20230815124643-0c8a013bdbee h1:ItHGipuUOFfWpffpsdnZQryCH/simnHmTDuju+GYwaM=
|
||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20230815124643-0c8a013bdbee/go.mod h1:l9S40lsDnTd/VAZjh1kmfYvz0B9z+7oT86pMQ/KurWo=
|
||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20231224145141-489e31b07a71 h1:nvVSH+Ju8EmoPiPHTae5lxHo4kDjROYChs19Yayz+NY=
|
||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20231224145141-489e31b07a71/go.mod h1:SrtvrQRdzt+8KfYzvosH++gWxo2ShPTzR1m3VQ6uX7U=
|
||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240130062251-a87a97b0e8d4 h1:93JYY8JLbFcrlq37q/uKyxs2r2e3modsjvfSbnZQ/UI=
|
||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240130062251-a87a97b0e8d4/go.mod h1:SrtvrQRdzt+8KfYzvosH++gWxo2ShPTzR1m3VQ6uX7U=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240612081722-31c64d4d4ce7 h1:QR8vMXOTy0NFKdodsGKA4gTNHJMfob3yRFYMXrZj7ek=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240612081722-31c64d4d4ce7/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240924065029-c865046cd9e7 h1:tyCPCMK+68PZ0axZylQHitMVp1d5mzNr9/YqMHXqo+A=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240924065029-c865046cd9e7/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241008084126-0b1c661317ee h1:4nuaCr5GQcx4z9/xWeEnjmLVV6J0j+QT68+AUKI9dFc=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241008084126-0b1c661317ee/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241009101340-1d415ef93cac h1:0V9ubWn7VLmefcPuuUfmmioNhdWQ9FeTXpwGCwbb3hE=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241009101340-1d415ef93cac/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241009101709-d8400fb206b4 h1:GUWgrIR7Gw1BIPzU6qUQgnB+7ZCE9nIwudAQTk7cyoU=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241009101709-d8400fb206b4/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241125081557-cacc6b3cafc6 h1:f24T6CtVn8bF84fbXpWTzS47otE+U2IdBj3cZero+OQ=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241125081557-cacc6b3cafc6/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250420100501-55e6ac5d835d h1:kWfJiJcJCaN3xEby1fepTg8Vy3umi7L54K/18on2bfw=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250420100501-55e6ac5d835d/go.mod h1:5p8CEKGBxi7qPtTXDI3HDmqKAfIm5i/aBWdrbkbdNjc=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250420101447-0b570213d5c7 h1:dmZ/mwRQ/AGlKXYWyk4Ci+KRiMcJwZii7nUCj2F2bpM=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250420101447-0b570213d5c7/go.mod h1:5p8CEKGBxi7qPtTXDI3HDmqKAfIm5i/aBWdrbkbdNjc=
|
||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211 h1:I/wOsRpCSRkU9vo1u703slQsmK0wnNeZzsWQOGtIAG0=
|
||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211/go.mod h1:SrtvrQRdzt+8KfYzvosH++gWxo2ShPTzR1m3VQ6uX7U=
|
||||
git.zhangdeman.cn/zhangdeman/logger v0.0.0-20230815063108-532ea798c348 h1:AE5kwFlumnFLnLQ1RIClwGtM1LXKo9TLxMgyc/WJI78=
|
||||
git.zhangdeman.cn/zhangdeman/logger v0.0.0-20230815063108-532ea798c348/go.mod h1:iVjdifEA/WPHsilfIp4jnDRM7w8ATGjlzMvsZhdtL1Y=
|
||||
git.zhangdeman.cn/zhangdeman/logger v0.0.0-20231008133508-da9b21010445 h1:yBpL6QqC5e4LS5LZgwnjeanUmbJleeCwvZ344EpR5Vg=
|
||||
git.zhangdeman.cn/zhangdeman/logger v0.0.0-20231008133508-da9b21010445/go.mod h1:qLJrvO4n5i0PjOCCcAQUMKDvsqf8QJRmMUDRk8yAw7g=
|
||||
git.zhangdeman.cn/zhangdeman/logger v0.0.0-20240308024848-54993a0ed4a6 h1:KeRD+IMkzk5RcHyJijT7tLRKW4wtulGcpG1dkKSr/5A=
|
||||
git.zhangdeman.cn/zhangdeman/logger v0.0.0-20240308024848-54993a0ed4a6/go.mod h1:IpTqawATar71MlLpheQAWrsXMqV2AxoZ3e0Vp3MeHNs=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20230815040629-5c584bcb7691 h1:Mdk0bAao3Plp7ck7WdnQE5WJkHjmHRw6N+jE4u/1jbQ=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20230815040629-5c584bcb7691/go.mod h1:UxkrpJIdDdgGkLsfmYVkUjGEFwbRkxbplWqUitpfca0=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20231224125439-01f39b6ea08d h1:TV0BCQQewBEtLsv3i9gXkxLFd5A5bWBTiNd3D/I5o4Q=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20231224125439-01f39b6ea08d/go.mod h1:w7kG4zyTJ1uPFaTWhze+OQuaUBINT2XnDxpyiM6ctc0=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240110090803-399e964daa0c h1:k7VCn9GfRGTilvdF/TcTFVMDBfKLe3VeGAtMTiDSnS0=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240110090803-399e964daa0c/go.mod h1:w7kG4zyTJ1uPFaTWhze+OQuaUBINT2XnDxpyiM6ctc0=
|
||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4 h1:s6d4b6yY+NaK1AzoBD1pxqsuygEHQz0Oie86c45geDw=
|
||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4/go.mod h1:V4Dfg1v/JVIZGEKCm6/aehs8hK+Xow1dkL1yiQymXlQ=
|
||||
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 h1:gUDlQMuJ4xNfP2Abl1Msmpa3fASLWYkNlqDFF/6GN0Y=
|
||||
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0/go.mod h1:VHb9qmhaPDAQDcS6vUiDCamYjZ4R5lD1XtVsh55KsMI=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240325080031-1f58204e8687 h1:uQcGqdzi4UdpZlp4f4FUPeBqoygP58pEKJkmN3ROsE0=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240325080031-1f58204e8687/go.mod h1:gf7SW2TXATgux8pfdFedMkXWv2515OtIIM/5c4atkFw=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240618035451-8d48a6bd39dd h1:2Y37waOVCmVvx0Rp8VGEptE2/2JVMImtxB4dKKDk/3w=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240618035451-8d48a6bd39dd/go.mod h1:6+7whkCmb4sJDIfH3HxNuXRveaM0gCCNWd2uXZqNtIE=
|
||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20230815042559-b34984be7444 h1:JVp575weLUX4sfhgjjxotJPxfHio7Ua8KHH3LMRRs2E=
|
||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20230815042559-b34984be7444/go.mod h1:IqS3vAMyt1fVCWS7RqGeUw1EFnL/ruUMha45G2T+YNM=
|
||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20231014142840-445c6407db92 h1:p1GVRYJc3NNoZeLs4CukitAbM3O/ALNq3l31cnbBQDM=
|
||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20231014142840-445c6407db92/go.mod h1:6OBeuwKy2J1TjdAwStEyC6aYC3kStmJiCg1eFC7g0fk=
|
||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20231227095334-7eb5cdbf9253 h1:GO3oZa5a2sqwAzGcLDJtQzmshSWRmoP7IDS8bwFqvC4=
|
||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20231227095334-7eb5cdbf9253/go.mod h1:VpPjBlwz8U+OxZuxzHQBv1aEEZ3pStH6bZvT21ADEbI=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241125081853-2d10d261da4c h1:BLcVowYti2mhYHZLFykocmbMJDMvFVg4lmXjDajhjD0=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241125081853-2d10d261da4c/go.mod h1:+D6uPSljwHywjVY5WSBY4TRVMj26TN5f5cFGEYMldjs=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd h1:q7GG14qgXKB4MEXQFOe7/UYebsqMfPaSX80TcPdOosI=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd/go.mod h1:+D6uPSljwHywjVY5WSBY4TRVMj26TN5f5cFGEYMldjs=
|
||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e h1:Q973S6CcWr1ICZhFI1STFOJ+KUImCl2BaIXm6YppBqI=
|
||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e/go.mod h1:VpPjBlwz8U+OxZuxzHQBv1aEEZ3pStH6bZvT21ADEbI=
|
||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240612083858-8d056baada2e h1:+PeWa2QdYBWnL32CfAAgy0dlaRCVNmYZDH4q+9w7Gfg=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240612083858-8d056baada2e/go.mod h1:US/pcq2vstE3iyxIHf53w8IeXKkZys7bj/ozLWkRYeE=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240924063449-ef80c6cb79d1 h1:LYw8NJeWcOiyrGjH9weyxnaMit94MlIngL+uskbLjtw=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240924063449-ef80c6cb79d1/go.mod h1:+2qNxuRsfyfOvXk9HNwn+CmyPmmhhrQm/eIi1FDU1jw=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20241125065949-2f87fe0cd90e h1:/N5yXmOEH7N/h4S6nv/6os8sRenh95BXogTZ2RJI950=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20241125065949-2f87fe0cd90e/go.mod h1:17TlhgwKTLQLIzYW/R6G39oN5FFPdsEEFDWniv+ovgA=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250321102712-1cbfbe959740 h1:zPUoylfJTbc0EcxW+NEzOTBmoeFZ2I/rLFBnEzxb4Wk=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250321102712-1cbfbe959740/go.mod h1:1ct92dbVc49pmXusA/iGfcQUJzcYmJ+cjAhgc3sDv1I=
|
||||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
|
||||
github.com/bytedance/sonic v1.10.0 h1:qtNZduETEIWJVIyDl01BeNxur2rW9OwTQ/yBqFRkKEk=
|
||||
github.com/bytedance/sonic v1.10.0/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
|
||||
github.com/bytedance/sonic v1.10.2 h1:GQebETVBxYB7JGWJtLBi07OVzWwt+8dWA00gEVW2ZFE=
|
||||
github.com/bytedance/sonic v1.10.2/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
|
||||
github.com/bytedance/sonic v1.11.2 h1:ywfwo0a/3j9HR8wsYGWsIWl2mvRsI950HyoxiBERw5A=
|
||||
github.com/bytedance/sonic v1.11.2/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
|
||||
github.com/bytedance/sonic v1.11.8 h1:Zw/j1KfiS+OYTi9lyB3bb0CFxPJVkM17k1wyDG32LRA=
|
||||
github.com/bytedance/sonic v1.11.8/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
|
||||
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg=
|
||||
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
||||
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
|
||||
github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo=
|
||||
github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
||||
github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0=
|
||||
github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
||||
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
|
||||
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||
github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I=
|
||||
github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
|
||||
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
|
||||
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
||||
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
|
||||
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.15.0 h1:nDU5XeOKtB3GEa+uB7GNYwhVKsgjAR7VgKoNB6ryXfw=
|
||||
github.com/go-playground/validator/v10 v10.15.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-playground/validator/v10 v10.16.0 h1:x+plE831WK4vaKHO/jpgUGsvLKIqRRkz6M78GuJAfGE=
|
||||
github.com/go-playground/validator/v10 v10.16.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4=
|
||||
github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||
github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao=
|
||||
github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||
github.com/go-redis/redis_rate/v9 v9.1.2 h1:H0l5VzoAtOE6ydd38j8MCq3ABlGLnvvbA1xDSVVCHgQ=
|
||||
github.com/go-redis/redis_rate/v9 v9.1.2/go.mod h1:oam2de2apSgRG8aJzwJddXbNu91Iyz1m8IKJE2vpvlQ=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
||||
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
|
||||
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8=
|
||||
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
|
||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4=
|
||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
|
||||
github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205AhTIGQQ=
|
||||
github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/go-redis/redismock/v9 v9.2.0 h1:ZrMYQeKPECZPjOj5u9eyOjg8Nnb0BS9lkVIZ6IpsKLw=
|
||||
github.com/go-redis/redismock/v9 v9.2.0/go.mod h1:18KHfGDK4Y6c2R0H38EUGWAdc7ZQS9gfYxc94k7rWT0=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/mozillazg/go-pinyin v0.20.0 h1:BtR3DsxpApHfKReaPO1fCqF4pThRwH9uwvXzm+GnMFQ=
|
||||
github.com/mozillazg/go-pinyin v0.20.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
||||
github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0=
|
||||
github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
|
||||
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/redis/go-redis/v9 v9.5.3 h1:fOAp1/uJG+ZtcITgZOfYFmTKPE7n4Vclj1wZFgRciUU=
|
||||
github.com/redis/go-redis/v9 v9.5.3/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
|
||||
github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4=
|
||||
github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA=
|
||||
github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E=
|
||||
github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
|
||||
github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM=
|
||||
github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA=
|
||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
|
||||
github.com/tidwall/gjson v1.16.0 h1:SyXa+dsSPpUlcwEDuKuEBJEz5vzTvOea+9rjyYodQFg=
|
||||
github.com/tidwall/gjson v1.16.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
||||
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c=
|
||||
go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk=
|
||||
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
|
||||
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc=
|
||||
golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.6.0 h1:S0JTfE48HbRj80+4tbvZDYsJ3tGv6BUU3XxyZ7CirAc=
|
||||
golang.org/x/arch v0.6.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
|
||||
golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
|
||||
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
|
||||
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
||||
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
|
||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
|
||||
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
|
31
monitor.go
31
monitor.go
@ -12,10 +12,9 @@ import (
|
||||
"strings"
|
||||
|
||||
"git.zhangdeman.cn/zhangdeman/util"
|
||||
redisClient "github.com/redis/go-redis/v9"
|
||||
|
||||
yml "gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/go-redis/redis/v8"
|
||||
)
|
||||
|
||||
// GetRedisServerInfo 获取 redis server info
|
||||
@ -23,7 +22,7 @@ import (
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 12:24 下午 2021/11/27
|
||||
func GetRedisServerInfo(client *redis.Client) (*ServerInfo, error) {
|
||||
func GetRedisServerInfo(client *redisClient.ClusterClient) (*ServerInfo, error) {
|
||||
var result ServerInfo
|
||||
if err := infoToStruct(client, "server", &result); nil != err {
|
||||
return nil, err
|
||||
@ -36,7 +35,7 @@ func GetRedisServerInfo(client *redis.Client) (*ServerInfo, error) {
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 12:59 下午 2021/11/27
|
||||
func GetMemoryInfo(client *redis.Client) (*MemoryInfo, error) {
|
||||
func GetMemoryInfo(client *redisClient.ClusterClient) (*MemoryInfo, error) {
|
||||
var result MemoryInfo
|
||||
if err := infoToStruct(client, "memory", &result); nil != err {
|
||||
return nil, err
|
||||
@ -49,7 +48,7 @@ func GetMemoryInfo(client *redis.Client) (*MemoryInfo, error) {
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 1:10 下午 2021/11/27
|
||||
func GetClientInfo(client *redis.Client) (*ClientInfo, error) {
|
||||
func GetClientInfo(client *redisClient.ClusterClient) (*ClientInfo, error) {
|
||||
var result ClientInfo
|
||||
if err := infoToStruct(client, "clients", &result); nil != err {
|
||||
return nil, err
|
||||
@ -62,7 +61,7 @@ func GetClientInfo(client *redis.Client) (*ClientInfo, error) {
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 1:11 下午 2021/11/27
|
||||
func GetPersistence(client *redis.Client) (*Persistence, error) {
|
||||
func GetPersistence(client *redisClient.ClusterClient) (*Persistence, error) {
|
||||
var result Persistence
|
||||
if err := infoToStruct(client, "persistence", &result); nil != err {
|
||||
return nil, err
|
||||
@ -75,7 +74,7 @@ func GetPersistence(client *redis.Client) (*Persistence, error) {
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 1:19 下午 2021/11/27
|
||||
func GetStats(client *redis.Client) (*Stats, error) {
|
||||
func GetStats(client *redisClient.ClusterClient) (*Stats, error) {
|
||||
var result Stats
|
||||
if err := infoToStruct(client, "stats", &result); nil != err {
|
||||
return nil, err
|
||||
@ -88,7 +87,7 @@ func GetStats(client *redis.Client) (*Stats, error) {
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 1:23 下午 2021/11/27
|
||||
func GetReplication(client *redis.Client) (*Replication, error) {
|
||||
func GetReplication(client *redisClient.ClusterClient) (*Replication, error) {
|
||||
var result Replication
|
||||
if err := infoToStruct(client, "replication", &result); nil != err {
|
||||
return nil, err
|
||||
@ -102,7 +101,7 @@ func GetReplication(client *redis.Client) (*Replication, error) {
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 4:26 下午 2021/11/27
|
||||
func GetSlaveList(client *redis.Client) []SlaveNode {
|
||||
func GetSlaveList(client *redisClient.ClusterClient) []SlaveNode {
|
||||
// 解析从库信息
|
||||
slaveList := make([]SlaveNode, 0)
|
||||
var data map[string]string
|
||||
@ -160,7 +159,7 @@ func GetSlaveList(client *redis.Client) []SlaveNode {
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 1:24 下午 2021/11/27
|
||||
func GetCPUInfo(client *redis.Client) (*CPU, error) {
|
||||
func GetCPUInfo(client *redisClient.ClusterClient) (*CPU, error) {
|
||||
var result CPU
|
||||
if err := infoToStruct(client, "cpu", &result); nil != err {
|
||||
return nil, err
|
||||
@ -173,7 +172,7 @@ func GetCPUInfo(client *redis.Client) (*CPU, error) {
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 1:27 下午 2021/11/27
|
||||
func GetCommandStats(client *redis.Client) (*Stats, error) {
|
||||
func GetCommandStats(client *redisClient.ClusterClient) (*Stats, error) {
|
||||
var result Stats
|
||||
if err := infoToStruct(client, "stats", &result); nil != err {
|
||||
return nil, err
|
||||
@ -186,7 +185,7 @@ func GetCommandStats(client *redis.Client) (*Stats, error) {
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 1:32 下午 2021/11/27
|
||||
func GetCommandInfo(client *redis.Client) ([]CmdStat, error) {
|
||||
func GetCommandInfo(client *redisClient.ClusterClient) ([]CmdStat, error) {
|
||||
var result map[string]string
|
||||
if err := infoToStruct(client, "commandstats", &result); nil != err {
|
||||
return make([]CmdStat, 0), err
|
||||
@ -237,7 +236,7 @@ func GetCommandInfo(client *redis.Client) ([]CmdStat, error) {
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2:44 下午 2021/11/27
|
||||
func GetKeyspace(client *redis.Client) ([]DB, error) {
|
||||
func GetKeyspace(client *redisClient.ClusterClient) ([]DB, error) {
|
||||
var result map[string]string
|
||||
if err := infoToStruct(client, "keyspace", &result); nil != err {
|
||||
return make([]DB, 0), err
|
||||
@ -278,7 +277,7 @@ func GetKeyspace(client *redis.Client) ([]DB, error) {
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 3:30 下午 2021/11/27
|
||||
func GetCluster(client *redis.Client) (*Cluster, error) {
|
||||
func GetCluster(client *redisClient.ClusterClient) (*Cluster, error) {
|
||||
var result Cluster
|
||||
if err := infoToStruct(client, "cluster", &result); nil != err {
|
||||
return nil, err
|
||||
@ -291,7 +290,7 @@ func GetCluster(client *redis.Client) (*Cluster, error) {
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 3:35 下午 2021/11/27
|
||||
func GetErrorStats(client *redis.Client) ([]Error, error) {
|
||||
func GetErrorStats(client *redisClient.ClusterClient) ([]Error, error) {
|
||||
var result map[string]string
|
||||
if err := infoToStruct(client, "errorstats", &result); nil != err {
|
||||
return make([]Error, 0), err
|
||||
@ -318,7 +317,7 @@ func GetErrorStats(client *redis.Client) ([]Error, error) {
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 12:28 下午 2021/11/27
|
||||
func infoToStruct(client *redis.Client, module string, receiver interface{}) error {
|
||||
func infoToStruct(client *redisClient.ClusterClient, module string, receiver interface{}) error {
|
||||
data := client.Info(context.Background(), module).String()
|
||||
// yaml 文件规范要求, key: val , 注意 : 的后面有空格
|
||||
data = strings.ReplaceAll(data, ":", ": ")
|
||||
|
@ -1,98 +0,0 @@
|
||||
// Package rate_limit ...
|
||||
//
|
||||
// Description : rate_limit ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2023-03-09 11:31
|
||||
package rate_limit
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
redisInstance "github.com/go-redis/redis/v8"
|
||||
"github.com/go-redis/redis_rate/v9"
|
||||
)
|
||||
|
||||
var (
|
||||
// limiter 限流实例
|
||||
limiter *redis_rate.Limiter
|
||||
)
|
||||
|
||||
// InitLimiter 初始化限流器实例
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 11:40 2023/3/9
|
||||
func InitLimiter(redisClient *redisInstance.Client) {
|
||||
limiter = redis_rate.NewLimiter(redisClient)
|
||||
}
|
||||
|
||||
// Second 每秒允许的访问数
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 11:42 2023/3/9
|
||||
func Second(ctx context.Context, key string, total, rate int) (bool, error) {
|
||||
if total <= 0 || rate <= 0 {
|
||||
return true, nil
|
||||
}
|
||||
res, err := limiter.AllowN(ctx, key, redis_rate.PerSecond(total), rate)
|
||||
if nil != err {
|
||||
return false, err
|
||||
}
|
||||
return res.Allowed > 0, nil
|
||||
}
|
||||
|
||||
// Minute 每分钟允许访问数
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 11:46 2023/3/9
|
||||
func Minute(ctx context.Context, key string, total, rate int) (bool, error) {
|
||||
if total <= 0 || rate <= 0 {
|
||||
return true, nil
|
||||
}
|
||||
res, err := limiter.AllowN(ctx, key, redis_rate.PerMinute(total), rate)
|
||||
if nil != err {
|
||||
return false, err
|
||||
}
|
||||
return res.Allowed > 0, nil
|
||||
}
|
||||
|
||||
// Hour 每小时允许访问数
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 11:47 2023/3/9
|
||||
func Hour(ctx context.Context, key string, total, rate int) (bool, error) {
|
||||
if total <= 0 || rate <= 0 {
|
||||
return true, nil
|
||||
}
|
||||
res, err := limiter.AllowN(ctx, key, redis_rate.PerHour(total), rate)
|
||||
if nil != err {
|
||||
return false, err
|
||||
}
|
||||
return res.Allowed > 0, nil
|
||||
}
|
||||
|
||||
// Day 每天允许访问数
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 11:47 2023/3/9
|
||||
func Day(ctx context.Context, key string, total, rate int) (bool, error) {
|
||||
if total <= 0 || rate <= 0 {
|
||||
return true, nil
|
||||
}
|
||||
res, err := limiter.AllowN(ctx, key, redis_rate.Limit{
|
||||
Rate: rate,
|
||||
Period: 24 * time.Hour,
|
||||
Burst: total,
|
||||
}, rate)
|
||||
if nil != err {
|
||||
return false, err
|
||||
}
|
||||
return res.Allowed > 0, nil
|
||||
}
|
41
wrapper.go
41
wrapper.go
@ -9,6 +9,7 @@ package redis
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.zhangdeman.cn/zhangdeman/consts"
|
||||
"git.zhangdeman.cn/zhangdeman/redis/define"
|
||||
"strings"
|
||||
"time"
|
||||
@ -26,13 +27,31 @@ var (
|
||||
type wrapper struct {
|
||||
}
|
||||
|
||||
// Exist 缓存Key是否存在
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 12:31 2024/6/21
|
||||
func (w *wrapper) Exist(ctx context.Context, instanceFlag string, key string) *define.RedisResult {
|
||||
return Client.Exec(ctx, instanceFlag, consts.RedisCommandExists, key)
|
||||
}
|
||||
|
||||
// TTL ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 18:14 2024/10/9
|
||||
func (w *wrapper) TTL(ctx context.Context, instanceFlag string, key string) *define.RedisResult {
|
||||
return Client.Exec(ctx, instanceFlag, consts.RedisCommandTTL, key)
|
||||
}
|
||||
|
||||
// Get Get命令
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 16:17 2024/6/19
|
||||
func (w *wrapper) Get(ctx context.Context, instanceFlag string, key string) *define.RedisResult {
|
||||
return Client.Exec(ctx, instanceFlag, "GET", key)
|
||||
return Client.Exec(ctx, instanceFlag, consts.RedisCommandGet, key)
|
||||
}
|
||||
|
||||
// Del 删除命令
|
||||
@ -41,7 +60,7 @@ func (w *wrapper) Get(ctx context.Context, instanceFlag string, key string) *def
|
||||
//
|
||||
// Date : 16:19 2024/6/19
|
||||
func (w *wrapper) Del(ctx context.Context, instanceFlag string, keyList ...string) *define.RedisResult {
|
||||
return Client.Exec(ctx, instanceFlag, "DEL", strings.Join(keyList, " "))
|
||||
return Client.Exec(ctx, instanceFlag, consts.RedisCommandDel, strings.Join(keyList, " "))
|
||||
}
|
||||
|
||||
// SetEx 设置数据并且带有效期, 有效期单位 : s
|
||||
@ -56,9 +75,9 @@ func (w *wrapper) SetEx(ctx context.Context, instanceFlag string, key string, va
|
||||
ttl = ttl - now
|
||||
}
|
||||
if withLock {
|
||||
return Client.Exec(ctx, instanceFlag, "SET", key, value, "EX", ttl, "NX")
|
||||
return Client.Exec(ctx, instanceFlag, consts.RedisCommandSet, key, value, "EX", ttl, "NX")
|
||||
}
|
||||
return Client.Exec(ctx, instanceFlag, "SET", key, value, "EX", ttl)
|
||||
return Client.Exec(ctx, instanceFlag, consts.RedisCommandSet, key, value, "EX", ttl)
|
||||
}
|
||||
|
||||
// LPop ...
|
||||
@ -67,7 +86,7 @@ func (w *wrapper) SetEx(ctx context.Context, instanceFlag string, key string, va
|
||||
//
|
||||
// Date : 16:29 2024/6/19
|
||||
func (w *wrapper) LPop(ctx context.Context, instanceFlag string, key string) *define.RedisResult {
|
||||
return Client.Exec(ctx, instanceFlag, "LPOP", key)
|
||||
return Client.Exec(ctx, instanceFlag, consts.RedisCommandLpop, key)
|
||||
}
|
||||
|
||||
// RPop ...
|
||||
@ -76,7 +95,7 @@ func (w *wrapper) LPop(ctx context.Context, instanceFlag string, key string) *de
|
||||
//
|
||||
// Date : 16:30 2024/6/19
|
||||
func (w *wrapper) RPop(ctx context.Context, instanceFlag string, key string) *define.RedisResult {
|
||||
return Client.Exec(ctx, instanceFlag, "RPOP", key)
|
||||
return Client.Exec(ctx, instanceFlag, consts.RedisCommandRpop, key)
|
||||
}
|
||||
|
||||
// LPush ...
|
||||
@ -85,7 +104,7 @@ func (w *wrapper) RPop(ctx context.Context, instanceFlag string, key string) *de
|
||||
//
|
||||
// Date : 16:31 2024/6/19
|
||||
func (w *wrapper) LPush(ctx context.Context, instanceFlag string, key string, value string) *define.RedisResult {
|
||||
return Client.Exec(ctx, instanceFlag, "LPUSH", key, value)
|
||||
return Client.Exec(ctx, instanceFlag, consts.RedisCommandLpush, key, value)
|
||||
}
|
||||
|
||||
// RPush ...
|
||||
@ -94,7 +113,7 @@ func (w *wrapper) LPush(ctx context.Context, instanceFlag string, key string, va
|
||||
//
|
||||
// Date : 16:31 2024/6/19
|
||||
func (w *wrapper) RPush(ctx context.Context, instanceFlag string, key string, value string) *define.RedisResult {
|
||||
return Client.Exec(ctx, instanceFlag, "RPUSH", key, value)
|
||||
return Client.Exec(ctx, instanceFlag, consts.RedisCommandRpush, key, value)
|
||||
}
|
||||
|
||||
// HGet ...
|
||||
@ -103,7 +122,7 @@ func (w *wrapper) RPush(ctx context.Context, instanceFlag string, key string, va
|
||||
//
|
||||
// Date : 16:33 2024/6/19
|
||||
func (w *wrapper) HGet(ctx context.Context, instanceFlag string, key string, field string) *define.RedisResult {
|
||||
return Client.Exec(ctx, instanceFlag, "HGET", key, field)
|
||||
return Client.Exec(ctx, instanceFlag, consts.RedisCommandHget, key, field)
|
||||
}
|
||||
|
||||
// HSet ...
|
||||
@ -112,7 +131,7 @@ func (w *wrapper) HGet(ctx context.Context, instanceFlag string, key string, fie
|
||||
//
|
||||
// Date : 16:33 2024/6/19
|
||||
func (w *wrapper) HSet(ctx context.Context, instanceFlag string, key string, field string, value string) *define.RedisResult {
|
||||
return Client.Exec(ctx, instanceFlag, "HSET", key, field, value)
|
||||
return Client.Exec(ctx, instanceFlag, consts.RedisCommandHset, key, field, value)
|
||||
}
|
||||
|
||||
// HDel ...
|
||||
@ -121,5 +140,5 @@ func (w *wrapper) HSet(ctx context.Context, instanceFlag string, key string, fie
|
||||
//
|
||||
// Date : 16:37 2024/6/19
|
||||
func (w *wrapper) HDel(ctx context.Context, instanceFlag string, key string, fieldList ...string) *define.RedisResult {
|
||||
return Client.Exec(ctx, instanceFlag, "HSET", key, strings.Join(fieldList, " "))
|
||||
return Client.Exec(ctx, instanceFlag, consts.RedisCommandHdel, key, strings.Join(fieldList, " "))
|
||||
}
|
||||
|
Reference in New Issue
Block a user