Redis连接拒绝问题90%源于服务端配置或网络:先查进程与端口监听,再核对bind(如仅127.0.0.1则无法远程连接)、protected-mode与requirepass是否冲突;Kratos连接池需合理设置PoolSize和MinIdleConns,避免耗尽;注意slowlog阻塞、ACL权限不足及context泄漏导致的连接池缓慢耗尽。

redis.Dial报错:Kratos启动时连不上Redis
Kratos默认用redis.Dial(底层基于github.com/go-redis/redis/v8)建连,但启动报错“connection refused”或“timeout”时,别急着改代码——90%的问题出在服务端配置或网络通路。先确认Redis进程是否真在监听:ps -ef | grep redis + netstat -tlnp | grep 6379;再看bind配置是不是只写了127.0.0.1,而Kratos服务跑在另一台机器上;还要检查protected-mode yes是否和requirepass冲突——没设密码又想远程连,Redis会直接拒掉。
连接池打满:Kratos接口P99飙升、日志刷timeout waiting for connection
Kratos本身不管理连接池,全靠redis.NewClient传入的redis.Options.PoolSize控制。常见错误是沿用默认值10,结果QPS一过500就卡死。注意:PoolSize不是最大连接数,而是“空闲+活跃”连接总数上限;如果业务并发高、命令耗时长(比如带Lua脚本),实际需要的连接数远高于QPS。建议按公式粗估:PoolSize ≥ QPS × 平均命令RTT(秒) × 2。另外必须配MinIdleConns(比如设为5),否则冷启动时所有请求都得排队等建连。
slowlog阻塞主线程:Kratos接口偶发性超时,但监控看不出CPU/内存异常
Kratos的gRPC或HTTP handler是同步执行的,一旦Redis命令被慢查询拖住,整个goroutine就卡住。这不是连接问题,但表现类似——客户端等不到响应。用redis-cli slowlog get 10查最近10条慢命令,重点看是否出现KEYS *、HGETALL大Hash、或LRANGE biglist 0 -1这类O(N)操作。Kratos项目里最容易踩坑的是:在@PostConstruct或init()阶段执行全量缓存预热,一次拉几万个key,直接把Redis主线程堵死几十秒。
ACL权限拒绝:Kratos报AUTH failed或NOAUTH Required,但密码明明是对的
Redis 6+默认启用ACL,老项目迁移到新版本后常栽在这儿。Kratos连接字符串里写的密码,可能只是default用户的密码,但你代码里用了SELECT 2切换库,或者执行了CONFIG GET这种管理命令——这些都需要显式授权。检查ACL规则:redis-cli --user default --pass xxx acl getuser default,确认输出里有on、~*(key权限)、@all(命令权限)。如果只是读写缓存,最小权限应为:resetchannels ~* "@read" "@write"。
最常被忽略的是连接池泄漏——Kratos里没手动client.Close(),但更隐蔽的是:中间件或拦截器里调用client.GetContext()后忘了用defer cancel(),导致context一直挂在那里,连接无法归还。这种情况不会立刻爆错,但压测几小时后connected_clients会缓慢爬升,直到池子耗尽。











