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

Redis连接不上主机报错,搞不清楚到底哪里断了线

知乎用户“码农小高”分享:

“哎,这个问题我可太有感触了,简直就是程序员的日常噩梦之一,你兴冲冲地写好了代码,一运行,啪,一个Could not connect to Redis at 127.0.0.1:6379: Connection refused或者类似的错误甩你脸上,瞬间就懵了,脑子里第一个念头就是:‘我啥也没动啊,怎么又连不上了?’

别慌,这种时候最忌讳的就是像无头苍蝇一样乱改配置,咱们得从最简单、最可能的地方开始,一步一步往外围排查,你就想象自己是个侦探,线索就藏在细节里。

第一站,也是最最最常见的:Redis服务本身到底启动了没有?

Redis连接不上主机报错,搞不清楚到底哪里断了线

很多人,包括我自己,都在这上面栽过跟头,你可能是用Docker跑的,可能是在服务器上直接安装的,但不管怎样,第一步先确认Redis这个‘家伙’是不是还活着,打开你的终端或者命令行:

  • 如果你是Linux或者Mac,试试命令:ps aux | grep redis,如果能看到redis-server的进程,那说明服务是在跑的,如果啥也没有,那就对了,问题就在这儿,赶紧把它启动起来,启动命令通常是redis-server,或者用系统服务systemctl start redis
  • 如果你是Windows,去服务列表里看看有没有一个叫Redis的服务,它的状态是不是‘已启动’。

有时候啊,你以为它启动了,其实它可能因为配置错误启动完立刻就崩溃退出了,最好再看看Redis的日志文件,日志文件的位置一般在Redis的配置文件里写着(通常是redis.conf),找找logfile这个配置项,打开日志,看看有没有什么致命的错误信息,比如权限问题啊、配置文件格式错误啊之类的,知乎上有个哥们儿就是因为配置文件里一个单词拼错了,折腾了一下午。

第二站,检查网络连通性:ping得通吗?

Redis连接不上主机报错,搞不清楚到底哪里断了线

如果服务确认是跑着的,那下一步就是看看你的电脑能不能‘找到’那台运行Redis的机器,这里分两种情况:

  1. Redis和你代码在同一台机器上(本地连接):这时候你用的地址通常是0.0.1或者localhost,你先别急着用代码连,用最原始的方法试试:打开终端,输入ping 127.0.0.1,如果正常回复,说明本地网络环回是没问题的,如果连这个都ping不通,那可能是你电脑的网络栈出了啥幺蛾子,这问题就比较底层了,但这种情况极少。
  2. Redis在另一台服务器上(远程连接):这是重灾区,用ping <服务器IP地址>命令,看看你的开发机能不能通到那台服务器,如果ping不通,那啥也别说了,就是网络不通,可能是IP地址写错了?可能是服务器关机了?可能是防火墙挡住了ICMP协议(ping请求)?甚至可能你连错了WiFi(比如连到了访客网络,访问不了内网)?这种低级错误我都犯过。

第三站,端口有没有被监听?防火墙是不是在捣乱?

好,假设现在ping是通的,说明两台机器之间物理上是能通信的,那为什么还连不上呢?很可能是因为Redis服务的‘门’(也就是端口)没开,或者被保安(防火墙)拦住了。

Redis连接不上主机报错,搞不清楚到底哪里断了线

  • 检查端口监听:在运行Redis的那台机器上,用命令netstat -tulnp | grep 6379(6379是Redis默认端口)看看,有没有一个进程在监听0.0.0:6379或者你的服务器IP:6379,如果显示监听的是0.0.1:6379,那坏事了,这表示Redis只允许本机连接,拒绝任何外部连接,这时候你就得去修改Redis的配置文件redis.conf,找到bind这一行,把它改成bind 0.0.0.0(允许所有IP连接,有安全风险,测试用可以)或者bind 你的服务器内网IP,然后重启Redis服务。
  • 检查防火墙:这是最烦人也是最容易忽略的一点,无论是服务器自带的防火墙(比如Linux的iptables或firewalld,Windows的Defender防火墙),还是云服务商(阿里云、腾讯云等)的安全组规则,都可能默认阻止掉6379端口。
    • 云服务器安全组:你一定要登录到云服务商的管理控制台,找到你的那台服务器实例,查看它的‘安全组’规则,确保有一条‘入方向’规则,允许访问6379端口,来源可以暂时设置为0.0.0/0(允许所有IP)来测试,生产环境肯定不能这么干。
    • 系统防火墙:在Linux上,可以用firewall-cmd --list-all(如果用的是firewalld)查看当前放行的端口和服务,如果没看到6379,就需要添加一条规则:sudo firewall-cmd --permanent --add-port=6379/tcp,然后重载防火墙。

第四站,核对连接配置:代码里的参数写对了吗?

如果前面三步都检查无误,那‘凶手’很可能就藏在你的代码或者配置文件中,定睛仔细看:

  • IP地址/主机名:确定没写错?是0.0.1还是localhost还是某个域名?域名能正确解析吗?
  • 端口号:你确定Redis服务运行在6379端口吗?有没有可能被改成了6380或者其他端口?回去看配置文件里的port选项。
  • 密码:如果Redis配置了密码(通过requirepass选项),那么你的连接代码里必须提供正确的密码,输错了密码,连接也会被拒绝。
  • 数据库编号:这个一般不会导致连接不上,但如果你连上了却操作不了数据,可以看看是不是选错了数据库索引(默认是0)。

CSDN博客“常见的Redis连接问题与解决方案”补充道:

“还有一种不那么常见但确实存在的情况是,Redis配置了保护模式(protected mode),当Redis没有设置密码,并且没有使用bind指令明确绑定到特定网络接口时,为了保护数据,它会默认进入保护模式,只接受来自0.0.1::1(IPv6的本地地址)的连接,如果你从外部网络连接,即使服务在运行、端口也监听者,也会被拒绝,解决方法要么是设置一个密码,要么是通过bind指令绑定你的服务器IP,或者(不推荐用于生产环境)将配置项protected-mode设置为no。”

Stack Overflow上的典型建议:

“当你把所有可能都检查了一遍还是不行时,尝试使用telnet命令来做一个最纯粹的网络连接测试,在客户端机器上运行telnet <Redis服务器IP> 6379,如果连接成功,你会看到一个黑色的空白窗口,光标在闪动,这证明TCP层面的连接是畅通的,问题大概率出在Redis的配置(如密码)或你的客户端代码上,如果telnet也连接失败,那么问题100%出在网络层面或Redis服务本身的状态上,请回到第一步重新仔细排查。”