当前位置:首页 > 问答 > 正文

搭Redis的时候突然连不上,折腾半天还是访问不了咋整

根据常见的Redis部署故障排查经验和社区讨论整理)

那天下午,我正打算给新项目接上Redis,一切配置看起来都挺美,用redis-cli连了一下,秒进,心里还美滋滋的,觉得这事儿稳了,结果等我代码写完,一跑起来,直接给我泼了盆冷水——连不上!控制台报错就像一堵墙,死死地挡在前面,什么“Connection refused”,什么“Timeout”,看得人头大。

我就不信这个邪了,重启大法好,先来一遍,sudo systemctl restart redis,回车,显示成功,再试,还是不行,心里咯噔一下,感觉要开始折腾了。

我怀疑是不是Redis服务压根儿没起来,或者起来又躺下了,赶紧查一下状态:sudo systemctl status redis,咦?状态显示是active (running),没问题啊,那为啥连不上呢?难道是防火墙?我用的云服务器,得检查安全组和系统本身的防火墙,ufw status一看,果然是inactive,没开,那问题就在云平台的安全组了,登录控制台,仔细核对,6379端口确实已经放行了,奇怪,这也不是。

搭Redis的时候突然连不上,折腾半天还是访问不了咋整

既然服务活着,网络通路看起来也没被阻断,那会不会是Redis自己“画地为牢”,不让我连呢?这时候我才想起来去看Redis的配置文件,通常叫redis.conf,用find命令把它找出来,然后vi打开,这一看,发现了第一个可疑点:bind配置,默认情况下,很多教程为了安全,会写成bind 127.0.0.1,这就意味着Redis只允许本机连接,我的应用要是部署在同一台机器上还好,但如果不在,那肯定连不上,我检查了一下,我的配置居然是bind 127.0.0.1 -::1,还是只允许本地,我试着把它注释掉(行首加#),或者改成bind 0.0.0.0,意思是允许所有IP连接,改完记得保存,然后又重启Redis服务。

满心期待地再试一次,结果……还是“Connection refused”!这下我真有点挠头了,冷静,再冷静,既然改了bind,会不会还有别的限制?继续在redis.conf里翻找,果然,又一个关键配置跳了出来:protected-mode,这个模式是为了防止在没设置密码的情况下被外部随意访问的,当bind注释掉(开放所有IP)且没设密码时,protected-mode默认是yes,它会拒绝外部连接,这算是一道安全防线,那我有两个选择:一是老老实实设置一个强密码(requirepass配置项),二是在测试环境临时把protected-mode改成no,为了快速验证,我先把它改成了no,再次重启Redis。

搭Redis的时候突然连不上,折腾半天还是访问不了咋整

心跳加速,再次尝试连接,哎?这次错误信息变了!不再是“Connection refused”,而是变成了“Operation timed out”,有门儿!这说明网络层面可能通了,Redis服务收到了我的连接请求,但为什么超时了呢?难道还有看不见的墙?

我突然想到,云服务商有时候会有一些隐藏的限制,某些云平台的云服务器,即便你安全组放行了端口,它可能还需要你配置一下服务器的内网/外网IP绑定,或者,是不是我连接的时候用的IP不对?我一直在用公网IP连,但Redis服务是不是只监听在内网网卡上?用命令netstat -tlnp | grep 6379看一下Redis到底监听在哪个地址上,输出显示是0.0.0.0:6379,这说明它确实在监听所有网络接口,那问题又回到了云平台。

我重新登录云平台控制台,把安全组规则删掉,又重新添加了一遍,这次特别注意了协议类型(TCP)和端口范围(6379/6379),确保源IP是我的开发机IP或者0.0.0.0/0(允许所有IP,仅测试用),保存应用后,抱着最后一丝希望,再次连接。

终于!熟悉的redis-cli提示符出现了!可以执行ping命令得到PONG响应了!那一刻,感觉像是解开了一个复杂的谜题,总结下来,我踩的坑主要有三个:一是Redis的bind绑定地址太局限;二是protected-mode的保护机制;三是云平台安全组规则可能需要反复确认才能生效,下次再遇到Redis突然连不上,别急着抓狂,就按这个顺序一步步捋:先看服务状态,再查防火墙和安全组,然后重点攻关Redis配置文件里的bind和protected-mode(以及密码),最后用netstat命令确认监听情况,大部分问题,都逃不出这几个地方。