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
分享

相关文章

10月 7, 2026

比尔盖茨的智慧:想多赚钱,就每天循环做这3件事

我们总有一种非常固执的错觉,认为那些站在财富金字塔顶端的人,必然拥有某种超越常人的特异功能。我们在脑海中给比尔盖茨这样的大佬描绘了一幅极其悲壮的奋斗画像。大家总觉得,他之所以能富可敌国,肯定是因为他每天只睡三个小时,同时对着八个电脑屏幕疯狂敲击键盘,每一秒钟都在做出价值几亿美金的生死抉择。 为了模仿

9月 28, 2026

程序员越想创业,越不要急着动手

一个能源方面的前辈找到我,希望通过我把一些人工的工作 AI 自动化。 能源方面我不懂,找 Gemini 聊完发现这个是可以复制的,非常兴奋。我跟老婆说,这个项目做好以后可以做成平台,推广到其他公司,你就等着做总裁夫人吧! 她听完以后跟我说,这个项目还是太定制化,和我之前做的一个项目很像。 那个项目一

9月 25, 2026

忍了一年多,我终于对i18n下手了过去一年,我主要参与国际机票业务的开发工作,因此每天都要和多语言(i18n)打交道

前言 大家好,我是奈德丽。 过去一年,我主要参与国际机票业务的开发工作,因此每天都要和多语言(i18n)打交道。熟悉我的朋友都知道,我这个人比较“惜力”(并不是,实际上只是忍不下去了),对于重复笨拙的工作非常抵触,于是,我开始思考如何优化团队的多语言管理模式。 痛点背景 先说说我们在机票项目中遇到的

下一篇

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

上一篇

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

最近更新

  • 比尔盖茨的智慧:想多赚钱,就每天循环做这3件事
  • iOS 侧载(Sideloading)工具
  • 程序员越想创业,越不要急着动手
  • 注册 Chat Participant
  • 中秋给在外游子的一封信

热门标签

API CodeGeex Coding Cursor DeepSeek Docker Gitkraken Harness Laravel Management

目录

©2026 mdo. 保留部分权利。