avatar

mdo

Hello

  • 首页
  • 知识库
  • 归档
  • 标签
  • 关于
主页 WebSocket Server + 独立 RPC Server
文章

WebSocket Server + 独立 RPC Server

发表于 2026-07-1 更新于 2026-07- 1
作者 mdo
12~15 分钟 阅读

从架构角度来说,它已经接近 think-swoole 能做到的极限了,但是我仍然不建议继续这样维护。

原因不是代码写法,而是 think-swoole 本身的事件模型。


第一处问题:addListener() 仍然共享 Worker

你的代码:

$rpcServer = $server->addListener(
    $config['host'],
    $config['port'],
    SWOOLE_SOCK_TCP
);

实际上得到的是:

           Master
              │
      ┌───────┴────────┐
      │                │
 HTTP 9501         TCP 9502
      │                │
      └───────┬────────┘
              │
         Worker0~7

不是:

HTTP Worker

RPC Worker

因此:

RPC 如果阻塞

例如:

sleep(3);

那么:

HTTP

WebSocket

RPC

都会抢同一组 Worker。


第二处问题:receive 被覆盖风险

这里:

$rpcServer->on('receive', ...)

而下面又注册了:

$server->on('request', ...)

还有

$server->on('handshake', ...)

目前还能工作,

但是以后如果:

  • think-swoole 升级

  • 插件增加

  • 自己新增事件

就很容易出现事件覆盖。

因为:

Server

↓

所有 Event 都挂在同一个对象

第三处问题:Sandbox 创建次数

你的 receive:

$sandbox = $this->app->make(Sandbox::class);

$sandbox->run(function () {

});

每一个 RPC:

都:

make Sandbox

↓

clone App

↓

run

↓

destroy

这和 HTTP 是一样的。

如果 RPC 很频繁:

例如:

10000 QPS

Sandbox 开销其实不小。


第四处问题:process_name

这里:

$server->on('start', ...)

只能修改

Master。

例如:

rpc master

而 Worker:

仍然叫:

swoole_http_server

因为:

WorkerStart

无法区分:

我是HTTP

还是RPC

第五处问题(也是最严重)

如果:

WebSocket

在线:

1000

广播:

每秒200次

RPC:

每秒5000请求

实际上:

Worker0

HTTP

RPC

push

都在一起

CPU 调度:

HTTP

↓

RPC

↓

push

↓

HTTP

↓

RPC

互相影响。


推荐改造

建议把现在这个 Service:

删掉。

变成:

app
 ├── command
 │      RpcStart.php
 │
 ├── rpc
 │      Server.php
 │
 ├── common
 │      rpc
 │          RpcService.php

RPC:

直接:

$server = new Swoole\Server(...);

不要:

Manager

↓

getServer()

↓

addListener()

WebSocket 保持不动

你的:

Handshake

Request

Message

Close

全部继续使用:

php think swoole

即可。


RPC 独立

例如:

php think rpc:start

Worker:

rpc worker 0

rpc worker 1

rpc worker 2

HTTP:

http worker 0

http worker 1

互不影响。


你的项目尤其建议拆分

因为根据我们之前几天讨论的情况,你的系统已经具备了这些特点:

  • ThinkPHP 6.1

  • think-swoole 4.8

  • WebSocket 在线约 1000

  • Redis Pub/Sub 广播

  • 独立 TCP RPC

  • TaskWorker

  • 已经出现过 worker exit timeout

  • 已经出现过 worker abnormal exit

  • 已经出现过 Sandbox not initialized

  • 正在做生产环境部署

这些都说明,你的应用已经不是一个简单的 HTTP 服务,而是一个长生命周期、多协议、高并发的系统。

在这种规模下,RPC 和 WebSocket 共用同一组 Worker,往往是后续性能瓶颈和稳定性问题的来源。将 RPC 独立为一个单独的 Swoole Server,可以做到:

  • 独立的 worker_num、max_request、dispatch_mode

  • 独立的重启与热更新,不影响 WebSocket 在线用户

  • Worker 崩溃互不影响

  • 更容易定位和排查问题

  • 后续如果 RPC 压力增大,还可以单独部署到另一台机器,而 WebSocket 服务无需改动

**如果你准备长期维护这个项目,我建议不要再基于 addListener() 扩展,而是直接采用“WebSocket Server + 独立 RPC Server”的双 Server 架构。

知识库
许可协议:  CC BY 4.0
分享

相关文章

7月 21, 2026

think-orm 2.0.62 单独设置数据表字段缓存驱动和数据缓存驱动

think-cache 拥有强大的多通道(Multi-store)管理能力,但问题的根源在于 think-orm 底层的调用机制太死板。即使您在 think-cache 中配置了 file 和 redis 两个完全独立的通道,think-orm 默认也只会向您通过 Db::setCache() 注入

7月 1, 2026

WebSocket Server + 独立 RPC Server

从架构角度来说,它已经接近 think-swoole 能做到的极限了,但是我仍然不建议继续这样维护。 原因不是代码写法,而是 think-swoole 本身的事件模型。 第一处问题:addListener() 仍然共享 Worker 你的代码: $rpcServer = $server->addLi

6月 25, 2026

Linux | Reqable · API抓包调试 + API测试一站式工具

Reqable是什么? Reqable = Fiddler + Charles + Postman 极简的设计、极高的性能、丰富的功能、桌面手机多端平台。 多协议流量分析 基于经典的MITM中间人代理方案捕获和分析您的应用流量,自适应HTTP/HTTPS/SOCKS4/SOCKS5等多种代理协议,并

下一篇

Redis 的发布/订阅(Pub/Sub) 机制

上一篇

think-orm 2.0.62 单独设置数据表字段缓存驱动和数据缓存驱动

最近更新

  • 完美地解决 TP3 老系统数据的平滑读取
  • thinkphp3 redis序列化和反序列化
  • Table 空间极易发生哈希冲突并溢出
  • 将监控程序直接跑在云端
  • AI 驱动型 Facebook 群组关键词监控 Chrome 浏览器插件

热门标签

API CodeGeex Gitkraken Management Manticore Premiere Sublime Swoole ThinkPHP ThinkPHP5

目录

©2026 mdo. 保留部分权利。