前提
报错信息
java.io.EOFException: null
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1293) ~[tomcat-embed-core-10.1.28.jar:10.1.28]
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.read(NioEndpoint.java:1181) ~[tomcat-embed-core-10.1.28.jar:10.1.28]
at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:74) ~[tomcat-embed-websocket-10.1.28.jar:10.1.28]
at org.apache.tomcat.websocket.server.WsFrameServer.doOnDataAvailable(WsFrameServer.java:184) ~[tomcat-embed-websocket-10.1.28.jar:10.1.28]
at org.apache.tomcat.websocket.server.WsFrameServer.notifyDataAvailable(WsFrameServer.java:164) ~[tomcat-embed-websocket-10.1.28.jar:10.1.28]
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch(WsHttpUpgradeHandler.java:152) ~[tomcat-embed-websocket-10.1.28.jar:10.1.28]
at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:60) ~[tomcat-embed-core-10.1.28.jar:10.1.28]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:57) ~[tomcat-embed-core-10.1.28.jar:10.1.28]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:904) ~[tomcat-embed-core-10.1.28.jar:10.1.28]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.28.jar:10.1.28]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.28.jar:10.1.28]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) ~[tomcat-embed-core-10.1.28.jar:10.1.28]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.28.jar:10.1.28]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.28.jar:10.1.28]
at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na]
pom.xml 文件 - 依赖版本
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>6.1.12</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.16</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
<version>10.1.28</version>
</dependency>
</dependencies>
解决方案
WebSocket 是长连接,默认的超时时间可能不够长,尤其是在连接空闲时,Nginx 会因超时关闭连接。
可以在 Nginx 配置中显式设置 proxy_read_timeout
和 proxy_connect_timeout
,以增加 WebSocket 连接的容忍时间。
增加 proxy_send_timeout
,这个配置可以帮助延长客户端发送数据到 Nginx 代理的超时时间。尽管 WebSocket 通常不会频繁发送数据,但添加这个设置可以确保连接稳定。
修改Nginx配置
原始配置
location / {
proxy_pass http://localhost:8081/websocket/message; # 将请求转发到 WebSocket 服务的具体路径
proxy_http_version 1.1; # 使用 HTTP/1.1
proxy_set_header Upgrade $http_upgrade; # WebSocket 升级支持
proxy_set_header Connection 'upgrade'; # WebSocket 升级支持
proxy_set_header Host $host; # 保留原始 Host 信息
proxy_cache_bypass $http_upgrade; # WebSocket 不使用缓存
}
修改后
location / {
proxy_pass http://localhost:8081/websocket/message;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
# 增加超时时间
proxy_connect_timeout 60s; # 设置连接超时(可根据需要调整)
proxy_read_timeout 3600s; # 设置读取超时,避免长时间不活动断开连接
proxy_send_timeout 3600s; # 设置发送超时
}
其他建议
调整 Nginx 的 worker_processes
和 worker_connections
:
如果服务器上有大量的并发 WebSocket 连接,可能需要增加 Nginx 的 worker_processes
和 worker_connections
设置,以提升处理并发连接的能力。
worker_processes auto; # 根据 CPU 核数自动设置
worker_connections 1024; # 每个进程最多能处理的连接数,视你的服务器能力而定
增加 keepalive_timeout
设置:
如果WebSocket 连接在空闲时容易掉线,考虑增加 keepalive_timeout
设置,确保 Nginx 和客户端保持连接。
keepalive_timeout 65; # 这个值可以根据需要调整,单位为秒