feat: slow threshold customizable in redis (#1187)
This commit is contained in:
@@ -1,11 +1,6 @@
|
|||||||
package redis
|
package redis
|
||||||
|
|
||||||
import (
|
import "errors"
|
||||||
"errors"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/tal-tech/go-zero/core/conf"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrEmptyHost is an error that indicates no redis host is set.
|
// ErrEmptyHost is an error that indicates no redis host is set.
|
||||||
@@ -19,11 +14,10 @@ var (
|
|||||||
type (
|
type (
|
||||||
// A RedisConf is a redis config.
|
// A RedisConf is a redis config.
|
||||||
RedisConf struct {
|
RedisConf struct {
|
||||||
Host string
|
Host string
|
||||||
Type string `json:",default=node,options=node|cluster"`
|
Type string `json:",default=node,options=node|cluster"`
|
||||||
Pass string `json:",optional"`
|
Pass string `json:",optional"`
|
||||||
Tls bool `json:",default=false,options=true|false"`
|
Tls bool `json:",default=false,options=true|false"`
|
||||||
SlowThreshold time.Duration `json:",default=100ms"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A RedisKeyConf is a redis config with key.
|
// A RedisKeyConf is a redis config with key.
|
||||||
@@ -42,9 +36,6 @@ func (rc RedisConf) NewRedis() *Redis {
|
|||||||
if len(rc.Pass) > 0 {
|
if len(rc.Pass) > 0 {
|
||||||
opts = append(opts, WithPass(rc.Pass))
|
opts = append(opts, WithPass(rc.Pass))
|
||||||
}
|
}
|
||||||
if rc.SlowThreshold > 0 {
|
|
||||||
opts = append(opts, WithSlowThreshold(conf.CheckedDuration(rc.SlowThreshold)))
|
|
||||||
}
|
|
||||||
if rc.Tls {
|
if rc.Tls {
|
||||||
opts = append(opts, WithTLS())
|
opts = append(opts, WithTLS())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package redis
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
red "github.com/go-redis/redis"
|
red "github.com/go-redis/redis"
|
||||||
"github.com/tal-tech/go-zero/core/logx"
|
"github.com/tal-tech/go-zero/core/logx"
|
||||||
@@ -10,26 +9,24 @@ import (
|
|||||||
"github.com/tal-tech/go-zero/core/timex"
|
"github.com/tal-tech/go-zero/core/timex"
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkDuration(slowThreshold time.Duration) func(proc func(red.Cmder) error) func(red.Cmder) error {
|
func checkDuration(proc func(red.Cmder) error) func(red.Cmder) error {
|
||||||
return func(proc func(red.Cmder) error) func(red.Cmder) error {
|
return func(cmd red.Cmder) error {
|
||||||
return func(cmd red.Cmder) error {
|
start := timex.Now()
|
||||||
start := timex.Now()
|
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
duration := timex.Since(start)
|
duration := timex.Since(start)
|
||||||
if duration > slowThreshold {
|
if duration > slowThreshold.Load() {
|
||||||
var buf strings.Builder
|
var buf strings.Builder
|
||||||
for i, arg := range cmd.Args() {
|
for i, arg := range cmd.Args() {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
buf.WriteByte(' ')
|
buf.WriteByte(' ')
|
||||||
}
|
|
||||||
buf.WriteString(mapping.Repr(arg))
|
|
||||||
}
|
}
|
||||||
logx.WithDuration(duration).Slowf("[REDIS] slowcall on executing: %s", buf.String())
|
buf.WriteString(mapping.Repr(arg))
|
||||||
}
|
}
|
||||||
}()
|
logx.WithDuration(duration).Slowf("[REDIS] slowcall on executing: %s", buf.String())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
return proc(cmd)
|
return proc(cmd)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
red "github.com/go-redis/redis"
|
red "github.com/go-redis/redis"
|
||||||
"github.com/tal-tech/go-zero/core/breaker"
|
"github.com/tal-tech/go-zero/core/breaker"
|
||||||
"github.com/tal-tech/go-zero/core/mapping"
|
"github.com/tal-tech/go-zero/core/mapping"
|
||||||
|
"github.com/tal-tech/go-zero/core/syncx"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -24,8 +25,11 @@ const (
|
|||||||
defaultSlowThreshold = time.Millisecond * 100
|
defaultSlowThreshold = time.Millisecond * 100
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrNilNode is an error that indicates a nil redis node.
|
var (
|
||||||
var ErrNilNode = errors.New("nil redis node")
|
// ErrNilNode is an error that indicates a nil redis node.
|
||||||
|
ErrNilNode = errors.New("nil redis node")
|
||||||
|
slowThreshold = syncx.ForAtomicDuration(defaultSlowThreshold)
|
||||||
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// Option defines the method to customize a Redis.
|
// Option defines the method to customize a Redis.
|
||||||
@@ -39,12 +43,11 @@ type (
|
|||||||
|
|
||||||
// Redis defines a redis node/cluster. It is thread-safe.
|
// Redis defines a redis node/cluster. It is thread-safe.
|
||||||
Redis struct {
|
Redis struct {
|
||||||
Addr string
|
Addr string
|
||||||
Type string
|
Type string
|
||||||
Pass string
|
Pass string
|
||||||
tls bool
|
tls bool
|
||||||
brk breaker.Breaker
|
brk breaker.Breaker
|
||||||
slowThreshold time.Duration
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RedisNode interface represents a redis node.
|
// RedisNode interface represents a redis node.
|
||||||
@@ -78,10 +81,9 @@ type (
|
|||||||
// New returns a Redis with given options.
|
// New returns a Redis with given options.
|
||||||
func New(addr string, opts ...Option) *Redis {
|
func New(addr string, opts ...Option) *Redis {
|
||||||
r := &Redis{
|
r := &Redis{
|
||||||
Addr: addr,
|
Addr: addr,
|
||||||
Type: NodeType,
|
Type: NodeType,
|
||||||
brk: breaker.NewBreaker(),
|
brk: breaker.NewBreaker(),
|
||||||
slowThreshold: defaultSlowThreshold,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
@@ -1759,6 +1761,11 @@ func Cluster() Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSlowThreshold sets the slow threshold.
|
||||||
|
func SetSlowThreshold(threshold time.Duration) {
|
||||||
|
slowThreshold.Set(threshold)
|
||||||
|
}
|
||||||
|
|
||||||
// WithPass customizes the given Redis with given password.
|
// WithPass customizes the given Redis with given password.
|
||||||
func WithPass(pass string) Option {
|
func WithPass(pass string) Option {
|
||||||
return func(r *Redis) {
|
return func(r *Redis) {
|
||||||
@@ -1766,13 +1773,6 @@ func WithPass(pass string) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithSlowThreshold sets the slow threshold.
|
|
||||||
func WithSlowThreshold(threshold time.Duration) Option {
|
|
||||||
return func(r *Redis) {
|
|
||||||
r.slowThreshold = threshold
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithTLS customizes the given Redis with TLS enabled.
|
// WithTLS customizes the given Redis with TLS enabled.
|
||||||
func WithTLS() Option {
|
func WithTLS() Option {
|
||||||
return func(r *Redis) {
|
return func(r *Redis) {
|
||||||
|
|||||||
@@ -1073,6 +1073,12 @@ func TestRedisGeo(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetSlowThreshold(t *testing.T) {
|
||||||
|
assert.Equal(t, defaultSlowThreshold, slowThreshold.Load())
|
||||||
|
SetSlowThreshold(time.Second)
|
||||||
|
assert.Equal(t, time.Second, slowThreshold.Load())
|
||||||
|
}
|
||||||
|
|
||||||
func TestRedis_WithPass(t *testing.T) {
|
func TestRedis_WithPass(t *testing.T) {
|
||||||
runOnRedis(t, func(client *Redis) {
|
runOnRedis(t, func(client *Redis) {
|
||||||
err := New(client.Addr, WithPass("any")).Ping()
|
err := New(client.Addr, WithPass("any")).Ping()
|
||||||
@@ -1115,7 +1121,7 @@ func runOnRedisTLS(t *testing.T, fn func(client *Redis)) {
|
|||||||
client.Close()
|
client.Close()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
fn(New(s.Addr(), WithTLS(), WithSlowThreshold(defaultSlowThreshold/2)))
|
fn(New(s.Addr(), WithTLS()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func badType() Option {
|
func badType() Option {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ func getClient(r *Redis) (*red.Client, error) {
|
|||||||
MinIdleConns: idleConns,
|
MinIdleConns: idleConns,
|
||||||
TLSConfig: tlsConfig,
|
TLSConfig: tlsConfig,
|
||||||
})
|
})
|
||||||
store.WrapProcess(checkDuration(r.slowThreshold))
|
store.WrapProcess(checkDuration)
|
||||||
return store, nil
|
return store, nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ func getCluster(r *Redis) (*red.ClusterClient, error) {
|
|||||||
MinIdleConns: idleConns,
|
MinIdleConns: idleConns,
|
||||||
TLSConfig: tlsConfig,
|
TLSConfig: tlsConfig,
|
||||||
})
|
})
|
||||||
store.WrapProcess(checkDuration(r.slowThreshold))
|
store.WrapProcess(checkDuration)
|
||||||
|
|
||||||
return store, nil
|
return store, nil
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user