You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Socket.IO频繁触发‘Session ID unknown’错误求助(代理场景)

Socket.IO 连接每隔1小时触发「Session ID unknown」故障排查

问题现象

基于 Node.js + Socket.IO 4.5.1 开发的项目,通过 Apache2 代理部署后整体运行正常,但每隔约1小时所有连接都会触发「Session ID unknown」错误,导致项目运行缓慢。更换为 Nginx 代理后问题依然存在。

环境版本

Apache2: Apache/2.4.54 (Ubuntu)
Socket.io Server: 4.5.1
Socket.io Client: 4.5.1

Apache 代理配置

<VirtualHost _default_:443>
    ServerName socket.myproject.com
    SSLEngine On
    SSLCertificateFile /etc/ssl/socket/primary.crt
    SSLCertificateKeyFile /etc/ssl/socket/private.key
    SSLCertificateChainFile /etc/ssl/socket/intermediate.crt
LoadModule authn_file_module            modules/mod_authn_file.so
LoadModule authn_core_module            modules/mod_authn_core.so
LoadModule authz_host_module            modules/mod_authz_host.so
LoadModule authz_groupfile_module       modules/mod_authz_groupfile.so
LoadModule authz_user_module            modules/mod_authz_user.so
LoadModule authz_core_module            modules/mod_authz_core.so
LoadModule headers_module               modules/mod_headers.so
LoadModule lbmethod_byrequests_module   modules/mod_lbmethod_byrequests.so
LoadModule proxy_module                 modules/mod_proxy.so
LoadModule proxy_balancer_module        modules/mod_proxy_balancer.so
LoadModule proxy_http_module            modules/mod_proxy_http.so
LoadModule proxy_wstunnel_module        modules/mod_proxy_wstunnel.so
LoadModule rewrite_module               modules/mod_rewrite.so
LoadModule slotmem_shm_module           modules/mod_slotmem_shm.so
# User daemon
# Group daemon
Header add Set-Cookie "SERVERID=sticky.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<Proxy "balancer://nodes_polling">
    BalancerMember "http://localhost:1002"    route=prod
    ProxySet stickysession=SERVERID
</Proxy>
<Proxy "balancer://nodes_ws">
    BalancerMember "ws://localhost:1002"    route=prod
    ProxySet stickysession=SERVERID
</Proxy>
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) balancer://nodes_ws/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule /(.*) balancer://nodes_polling/$1 [P,L]
ProxyTimeout 3
</VirtualHost>

客户端代码

this.IO = io(AppConstants.socketBaseUrl, {
  query: { token:"blablabla...." },
  path: '/socket.io',
  withCredentials: true,
  transports: ['websocket', 'polling'],
  secure: true,
});

服务端代码

const socketServer = require('socket.io')(Server, {
  transports: ['websocket', 'polling'],
  cors: {
    origin: '*',
    credentials: true,
    methods: ['GET', 'POST'],
  },
});

排查与解决思路

1. 调整代理超时配置

当前 Apache 配置的 ProxyTimeout 3 仅为3秒,会导致代理层主动断开长连接。Socket.IO 长连接需要足够的超时时间,建议将 ProxyTimeout 调整为 3600(1小时)以上,或设置为 0 禁用超时(需结合业务场景评估)。

2. 固化 Socket.IO 会话存储

默认情况下 Socket.IO 会话存在内存中,服务重启或内存回收会导致会话丢失。建议使用 Redis 外部存储持久化会话:

const { createAdapter } = require('@socket.io/redis-adapter');
const { createClient } = require('redis');

const pubClient = createClient({ url: 'redis://localhost:6379' });
const subClient = pubClient.duplicate();

Promise.all([pubClient.connect(), subClient.connect()]).then(() => {
  socketServer.adapter(createAdapter(pubClient, subClient));
});

3. 优化 Socket.IO 心跳配置

显式配置服务端心跳参数,确保会话保持:

const socketServer = require('socket.io')(Server, {
  transports: ['websocket', 'polling'],
  cors: {
    origin: '*',
    credentials: true,
    methods: ['GET', 'POST'],
  },
  pingInterval: 25000, // 25秒发送一次心跳
  pingTimeout: 60000, // 60秒未收到响应则断开
});

4. 完善客户端重连逻辑

添加客户端断开监听,确保异常断开后自动重连:

this.IO.on('disconnect', (reason) => {
  console.log('连接断开:', reason);
  if (reason !== 'io client disconnect') {
    this.IO.connect();
  }
});

5. 排查代理层连接限制

  • 检查 Apache 的 MaxRequestWorkers、MaxConnectionsPerChild 参数,确保能容纳当前并发连接数。
  • 若使用 Nginx,需配置长连接支持:
    location /socket.io {
      proxy_pass http://localhost:1002;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_set_header Host $host;
      proxy_read_timeout 3600s;
      proxy_send_timeout 3600s;
    }
    

6. 开启日志排查

  • 服务端开启 Socket.IO 调试日志,追踪会话丢失细节:
    DEBUG=socket.io* node your-server-file.js
    
  • 查看 Apache/Nginx 的访问日志、错误日志,确认是否有代理层主动断开连接的记录。

内容的提问来源于stack exchange,提问作者Ahmad Echem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 03:03:20