Redis 运行一直正常,今天照例巡查,发现无法连接到Redis,并且得到如下错误信息:
Could not connect to Redis at 127.0.0.1:6379: 由于系统缓冲区空间不足或队列已满
如下图:
打开 DOS 窗口,输入“netstat -ano”命令查看本机端口使用情况。发现本机端口已经分配到 65535 了,没有多余的端口分配了,导致连接到 redis 失败。命令输出如下:
协议 本地地址 外部地址 状态 PID TCP 127.0.0.1:49156 127.0.0.1:49157 ESTABLISHED 1412 TCP 127.0.0.1:49156 127.0.0.1:49158 ESTABLISHED 24228 TCP 127.0.0.1:49156 127.0.0.1:65535 ESTABLISHED 24228 TCP 127.0.0.1:49157 127.0.0.1:49156 ESTABLISHED 1412 ...... TCP 127.0.0.1:65535 127.0.0.1:49156 ESTABLISHED 24228 TCP 127.0.0.1:65535 127.0.0.1:49159 ESTABLISHED 24228 TCP 127.0.0.1:65535 127.0.0.1:65527 ESTABLISHED 24228
如果你要连接到 Redis 服务器,Redis 服务本身监听 6379 端口,而客户端也需要分配一个动态端口用于两者通信。你可以尝试关闭 Java 服务,临时解决上面的问题;要彻底解决该问题你需要分析你的Java服务,为什么会分配那么多的动态端口。我以自己碰到的问题为例:
因为我使用了 Netty 框架,而 Netty 框架采用了 NIO 多路复用技术。因此,Windows下,Selector.open() 会自己和自己建立两条 TCP 链接。不但消耗了两个 TCP 连接和端口,同时也消耗了文件描述符。更多关于 Java NIO类库Selector机制解析,请参考:https://blog.csdn.net/haoel/article/details/2224055
注意:你可以使用 jvisualvm 工具监听 java 服务,然后查看线程情况,会发现有很多名为 NioEventLoopGroup 的线程,一个线程就调用了一个 Selector.open() 方法,即占用两个端口。
TCP端口和UDP端口。由于TCP和UDP 两个协议是独立的,因此各自的端口号也相互独立,比如TCP有235端口,UDP也 可以有235端口,两者并不冲突。
周知端口是众所周知的端口号,范围从0到1023,其中80端口分配给WWW服务,21端口分配给FTP服务等。我们在IE的地址栏里输入一个网址的时候是不必指定端口号的,因为在默认情况下WWW服务的端口是“80”。
网络服务是可以使用其他端口号的,如果不是默认的端口号则应该在 地址栏上指定端口号,方法是在地址后面加上冒号“:”(半角),再加上端口号。比如使用“8080”作为WWW服务的端口,则需要在地址栏里输入“网址:8080”。
但是有些系统协议使用固定的端口号,它是不能被改变的,比如139 端口专门用于NetBIOS与TCP/IP之间的通信,不能手动改变。
端口1024到49151,分配给用户进程或应用程序。这些进程主要是用户选择安装的一些应用程序,而不是已经分配好了公认端口的常用程序。这些端口在没有被服务器资源占用的时候,可以用用户端动态选用为源端口。
动态端口的范围是从49152到65535。之所以称为动态端口,是因为它 一般不固定分配某种服务,而是动态分配。