Table 空间极易发生哈希冲突并溢出
既然你没有在业务中主动调用 Room,只使用了全局广播,那么这个问题就非常明确了:即使你不用房间功能,think-swoole 只要开启了 WebSocket,底层就会强行初始化并注入一个名为 Room 的驱动组件。 [1]
框架底层默认使用 table 类型来作为 Room 的存储介质。当进行全局广播时,底层需要去检索和遍历连接数据。随着连接数和并发增加,系统自带的默认 Table 空间极易发生哈希冲突并溢出。 [1]
针对你的情况(仅做全局广播,无复杂分组需求),可以通过以下两个最优方案来彻底解决 table set 报错。
方案一:一劳永逸,直接切换为 redis 驱动(强烈推荐 ⭐⭐⭐⭐⭐)
直接将底层的组件介质从内存表(table)切换为 Redis。Redis 在处理海量连接和高频读写时更加稳定,且彻底消除了 Swoole Table 固有的内存大小限制与哈希冲突问题。 [1]
打开 config/swoole.php,找到 websocket.room 配置项,修改如下: [1]
php
'room' => [
'type' => 'redis', // 将 'table' 修改为 'redis'
'redis' => [
'host' => '127.0.0.1',
'port' => 6379,
// ...配置密码和连接池
],
],
请谨慎使用此类代码。
方案二:撑大底层默认的内置参数(仅保留 Table 时的做法)
若不想使用 Redis,需在 config/swoole.php 中增大默认 table 的容量。重点是将 client_rows 修改为 2 的幂次方(如 32768 或 65536): [1]
php
'room' => [
'type' => 'table',
'table' => [
'room_rows' => 32768,
'client_rows' => 65536, // 调大此值以容纳更多广播连接
],
],
请谨慎使用此类代码。
⚠️ 关键提示
修改配置文件后,必须重启服务方可生效,热重载(reload)无效: [1, 2]
bash
php think swoole restart
请谨慎使用此类代码。
请问修改为 Redis 驱动 或者 调大 client_rows 之后,服务重启后是否还继续报错?如果还有报错,可以把最新的报错日志贴出来吗?
许可协议:
CC BY 4.0