modulepackage
1.0.3
Repository: https://github.com/soedev/soego-component.git
Documentation: pkg.go.dev
# README
eredis 组件使用指南
1 简介
对 go-redis 进行了轻量封装,并提供了以下功能:
- 规范了标准配置格式,提供了统一的 Load().Build() 方法。
- 支持自定义拦截器
- 提供了默认的 Debug 拦截器,开启 Debug 后可输出 Request、Response 至终端。
- 提供了默认的 Metric 拦截器,开启后可采集 Prometheus 指标数据
- 提供了默认的 OpenTelemetry 拦截器,开启后可采集 Tracing Span 数据
- 提供了redis的分布式锁
- 提供了redis的分布式锁的定时任务
2 使用方式
go get github.com/soedev/soego-component/eredis
3 Redis配置
type config struct {
Addrs []string // Addrs 实例配置地址
Addr string // Addr stubConfig 实例配置地址
Mode string // Mode Redis模式 cluster|stub|sentinel
MasterName string // MasterName 哨兵主节点名称,sentinel模式下需要配置此项
Password string // Password 密码
DB int // DB,默认为0, 一般应用不推荐使用DB分片
PoolSize int // PoolSize 集群内每个节点的最大连接池限制 默认每个CPU10个连接
MaxRetries int // MaxRetries 网络相关的错误最大重试次数 默认8次
MinIdleConns int // MinIdleConns 最小空闲连接数
DialTimeout time.Duration // DialTimeout 拨超时时间
ReadTimeout time.Duration // ReadTimeout 读超时 默认3s
WriteTimeout time.Duration // WriteTimeout 读超时 默认3s
IdleTimeout time.Duration // IdleTimeout 连接最大空闲时间,默认60s, 超过该时间,连接会被主动关闭
Debug bool // Debug开关, 是否开启调试,默认不开启,开启后并加上export EGO_DEBUG=true,可以看到每次请求,配置名、地址、耗时、请求数据、响应数据
ReadOnly bool // ReadOnly 集群模式 在从属节点上启用读模式
SlowLogThreshold time.Duration // 慢日志门限值,超过该门限值的请求,将被记录到慢日志中
OnFail string // OnFail panic|error
EnableMetricInterceptor bool // 是否开启监控,默认开启
EnableTraceInterceptor bool // 是否开启链路,默认开启
EnableAccessInterceptor bool // 是否开启,记录请求数据
EnableAccessInterceptorReq bool // 是否开启记录请求参数
EnableAccessInterceptorRes bool // 是否开启记录响应参数
}
4 普通Redis查询
4.1 用户配置
# 常用的stub单实例配置示例
[redis.stub]
debug = true # ego增加redis debug,打开后可以看到,配置名、地址、耗时、请求数据、响应数据
mode = "stub" # 默认为stub单实例模式,可选"stub|cluster|sentinel"
addr = "127.0.0.1:6379"
# cluster集群模式配置示例
[redis.cluster]
debug = true
mode = "cluster" # 设置为"cluster"模式,该模式下必须配置"addrs"
addrs = ["127.0.0.1:6379", "127.0.0.1:6380", "127.0.0.1:6381"] # cluster模式下必须配置"addrs"
# sentinel哨兵模式配置示例
[redis.sentinel]
debug = true
mode = "sentinel" # 设置为"sentinel"模式,该模式下必须配置"addrs"和"masterName"
addrs = ["127.0.0.1:26379", "127.0.0.1:26380", "127.0.0.1:26381"] # sentinel模式下必须配置"addrs"
masterName = "my-sentinel-master-name" # sentinel 模式下必须配置"masterName"
4.2 优雅的Debug
通过开启 debug
配置和命令行的 export EGO_DEBUG=true
,我们就可以在测试环境里看到请求里的配置名、地址、耗时、请求数据、响应数据
4.3 用户代码
配置创建一个 redis
的配置项,其中内容按照上文配置进行填写。以上这个示例里这个配置key是redis.test
代码中创建一个 redis
实例 eredis.Load("key").Build()
,代码中的 key
和配置中的 key
要保持一致。创建完 redis
实例后,就可以直接使用他对 redis
进行 crud
。
package main
import (
"fmt"
"github.com/soedev/soego"
"github.com/soedev/soego-component/eredis"
"github.com/soedev/soego/core/elog"
)
// export EGO_DEBUG=true && go run main.go --config=config.toml
func main() {
err := ego.New().Invoker(
invokerRedis,
testRedis,
).Run()
if err != nil {
elog.Panic("startup", elog.FieldErr(err))
}
}
var eredisStubClient *eredis.Component
var eredisClusterClient *eredis.Component
var eredisSentinelClient *eredis.Component
func invokerRedis() error {
// 读取"redis.stub"配置,并初始化redis stub component实例
eredisStubClient = eredis.Load("redis.stub").Build()
// 读取"redis.cluster"配置,并初始化redis cluster component实例
eredisClusterClient = eredis.Load("redis.cluster").Build()
// 读取"redis.sentinel"配置,并初始化redis sentinel component实例
eredisSentinelClient = eredis.Load("redis.sentinel").Build()
return nil
}
func testRedis() error {
// 使用redis stub component进行set、get操作
err := eredisStubClient.Set(context.Background(), "hello", "world", 0)
if err != nil {
log.Println(err)
}
str, err := eredisStubClient.Get(context.Background(), "hello")
if err != nil {
log.Println(err)
}
fmt.Println(str)
// 使用redis cluster component进行set、get操作
err := eredisClusterClient.Set(context.Background(), "hello", "world", 0)
if err != nil {
log.Println(err)
}
str, err := eredisClusterClient.Get(context.Background(), "hello")
if err != nil {
log.Println(err)
}
fmt.Println(str)
return nil
// 使用redis sentinel component进行set、get操作
err := eredisSentinelClient.Set(context.Background(), "hello", "world", 0)
if err != nil {
log.Println(err)
}
str, err := eredisSentinelClient.Get(context.Background(), "hello")
if err != nil {
log.Println(err)
}
fmt.Println(str)
return nil
}
5 Redis的日志
任何redis的请求都会记录redis的错误access日志,如果需要对redis的日志做定制化处理,可参考以下使用方式。
5.1 开启redis的access日志
线上在并发量不高,或者核心业务下可以开启全量access日志,这样方便我们排查问题
5.2 开启日志方式
在原有的redis配置中,加入以下三行配置,redis的日志里就会记录响应的数据
[redis.test]
enableAccessInterceptor=true # 是否开启,记录请求数据
enableAccessInterceptorReq=true # 是否开启记录请求参数
enableAccessInterceptorRes=true # 是否开启记录响应参数
5.3 开启自定义日志字段的数据
在使用了ego的自定义字段功能export EGO_LOG_EXTRA_KEYS=X-Ego-Uid
,将对应的数据塞入到context中,那么redis的access日志就可以记录对应字段信息。
参考 详细文档 :
func testRedis() error {
ctx := context.Background()
ctx = context.WithValue(ctx, "X-Ego-Uid", 9527)
err := eredisClient.Set(ctx, "hello", "world", 0)
fmt.Println("set hello", err)
str, err := eredisClient.Get(ctx, "hello")
fmt.Println("get hello", str, err)
str, err = eredisClient.Get(ctx, "lee")
fmt.Println("Get lee", errors.Is(err, eredis.Nil), "err="+err.Error())
return nil
}
6 Redis的定时任务锁
// export EGO_DEBUG=true && go run main.go --config=config.toml
func main() {
err := ego.New().Invoker(initRedis).Cron(cronJob()).Run()
if err != nil {
elog.Panic("startup", elog.FieldErr(err))
}
}
func initRedis() error {
redis = eredis.Load("redis.test").Build()
return nil
}
func cronJob() ecron.Ecron {
locker := ecronlock.DefaultContainer().Build(ecronlock.WithClient(redis))
cron := ecron.Load("cron.default").Build(
ecron.WithLock(locker.NewLock("soedev/soego-component:cronjob:syncXxx")),
ecron.WithJob(helloWorld),
)
return cron
}
func helloWorld(ctx context.Context) error {
log.Println("cron job running")
return nil
}
7 Redis监控数据
# Functions
DefaultConfig default config ...
DefaultContainer 定义了默认Container配置.
ExponentialBackoffRetry strategy is an optimization strategy with a retry time of 2**n milliseconds (n means number of times).
LimitRetry limits the number of retries to max attempts.
LinearBackoffRetry allows retries regularly with customized intervals.
Load 载入配置,初始化Container.
--------------------------------No Retry----------------------------------- NoRetry acquire the Lock only once.
WithAddr set address.
WithAddrs set addresses.
WithStub set mode to "cluster".
No description provided by the author
No description provided by the author
WithMasterName set masterName for sentinel mode.
WithPassword set password.
WithPoolSize set pool size.
WithStub set mode to "sentinel".
WithStub set mode to "stub".
# Constants
ClusterMode using clusterClient.
ErrInvalidParams is returned when parameters is invalid.
ErrLockNotHeld is returned when trying to release an inactive Lock.
ErrNotObtained is returned when a Lock cannot be obtained.
Nil reply returned by Redis when key does not exist.
No description provided by the author
SentinelMode using Failover sentinel client.
StubMode using stubClient.
# Interfaces
RetryStrategy allows to customise the Lock retry strategy.
# Type aliases
No description provided by the author
No description provided by the author
No description provided by the author