最常见原因有五个:Redis服务未启动或端口不匹配;bind和protected-mode双重封锁;Laravel配置与Redis实例不匹配;防火墙/安全组/VPC网络策略拦截;多条件叠加故障。

最常见原因就五个,90% 的 RedisException: Connection refused 都能在这里面找到根子。
Redis 服务根本没起来或端口不对
别急着改代码,先确认 Redis 进程在不在。Laravel 报错前,redis-cli ping 就该返回 PONG;如果连这个都失败,说明服务压根没运行,或者监听的端口不是你 .env 里写的那个。
- 用
sudo systemctl status redis看服务状态,没运行就start - 查实际监听端口:
ss -tlnp | grep :6379(把6379换成你怀疑的端口) - 如果 Redis 被手动改过端口(比如改成
6999),.env里的REDIS_PORT必须同步改,否则 Laravel 会固执地连6379
bind 和 protected-mode 双重封锁
这是本地开发能通、一上服务器就跪的头号元凶。默认配置下,Redis 只绑 127.0.0.1,且 protected-mode yes —— 外部请求直接被拒,错误表现就是连接被拒绝,而不是认证失败。
- 检查
/etc/redis/redis.conf:确认bind是否包含你的应用服务器 IP(如bind 127.0.0.1 192.168.1.100),或明确放开到内网段(不建议用0.0.0.0) - 若未设密码,
protected-mode yes会强制只接受本地连接;临时验证可执行redis-cli CONFIG SET protected-mode no,但生产环境必须配密码 + 合理 bind - 改完配置记得
sudo systemctl restart redis,否则 reload 不生效
Laravel 配置和 Redis 实例不匹配
哪怕 Redis 服务开着、网络通着,Laravel 自己的配置错一个字符也会断连。尤其注意 database 和 password 这两个容易被忽略的坑。
-
REDIS_PASSWORD=null在.env里会被解析成字符串"null",而非 PHP 的null值,导致发过去一个无效密码;应写成REDIS_PASSWORD=(空值)或留空 -
REDIS_DEFAULT_DATABASE=0如果写成REDIS_DEFAULT_DATABASE=(后面没值),Laravel 会传空字符串给SELECT命令,报ERR invalid DB index;必须写成REDIS_DEFAULT_DATABASE=0或删掉这行让默认逻辑生效 - 检查
config/database.php里'client'是phpredis还是predis,两者对超时、持久化等参数处理不同,混用可能出诡异行为
防火墙 / 安全组 / VPC 网络策略拦路
云环境里,比配置错误更隐蔽的是网络层拦截。Redis 服务自己没问题,但中间有道墙不让过。
- 本地测试用
telnet your-redis-ip 6379或nc -zv your-redis-ip 6379,不通就不是 Laravel 的问题 - 云服务器要查两处:ECS 所在安全组(出方向)、Redis 实例所在安全组(入方向),都得放行对应端口
- 跨 VPC 访问必须配 VPC 对等连接或云企业网 CEN;白名单功能开启后,客户端 IP 必须显式加入,IP 变动就得重新加
真正麻烦的往往不是单点故障,而是多个条件叠加:比如 Redis 绑了内网 IP + 保护模式开着 + 安全组没开 + Laravel 配了错端口。排查时别跳步,从服务进程、端口、配置、网络、客户端五层一层敲实,比盲目重启快得多。


















