avatar

mdo

Hello

  • 首页
  • 知识库
  • 归档
  • 标签
  • 关于
主页 为 RPC 端口和 Websocket 端口配置独立的 Worker 进程
文章

为 RPC 端口和 Websocket 端口配置独立的 Worker 进程

发表于 2026-06-29 更新于 2026-06- 29
作者 mdo
11~15 分钟 阅读

在标准的 Swoole 中,子服务器端口(listen 产生的 Swoole\Server\Port)只能单独设置网络协议参数,无法直接通过 set(['worker_num' => X]) 来独立设置 Worker 进程数量。也就是说,默认情况下它们必然会共享主服务器的 Worker 进程。

为了真正实现 RPC 端口和 Websocket 端口的 Worker 进程隔离,在 think-swoole 架构下有以下两种最佳实践方案:


方案一:通过多进程自定义进程(Process)进行隔离(推荐)

这是在一个 ThinkPHP 项目中实现隔离的最佳方式。让主进程(9512)只负责 Websocket 和 HTTP,而 RPC 服务(9513)不再作为子端口监听,而是通过 Swoole 的 Custom Process(自定义进程) 单独启动一个独立的 RPC 服务器。

1. 修改 config/swoole.php

关闭 ports 中的 RPC 配置,改为在 custom_process 中注册一个自定义进程:

php

return [
    'server' => [
        'host' => '0.0.0.0',
        'port' => 9512, // 9512 专门给 Websocket / HTTP 使用
        'options' => [
            'worker_num' => 4, // 这里的 4 个 Worker 专门处理 Websocket
        ],
    ],
    // 清空原有的 ports 监听,防止冲突
    'ports' => [], 
    
    // 注册自定义进程来运行 RPC 服务
    'custom_process' => [
        'rpc_server_process' => \app\process\RpcServerProcess::class,
    ],
];

请谨慎使用此类代码。

2. 创建自定义进程类 app/process/RpcServerProcess.php

利用 Swoole 原生的 Server 在独立进程中监听 9513 端口。这样 RPC 拥有自己独立的事件轮询,绝不受 Websocket 广播影响。

php

<?php
namespace app\process;

use think\swoole\contract\ProcessInterface;
use Swoole\Process as SwooleProcess;
use Swoole\Server as SwooleServer;

class RpcServerProcess implements ProcessInterface
{
    public function __construct() {}

    public function handle(SwooleProcess $process)
    {
        // 创建一个纯 TCP 的 RPC 服务器,运行在这个独立进程中
        // 注意:此处使用 Swoole\Server 即可,也可以根据框架的 RPC 协议进行解析
        $server = new SwooleServer('0.0.0.0', 9513, SWOOLE_PROCESS, SWOOLE_SOCK_TCP);
        
        $server->set([
            'worker_num' => 2, // 🔥 这里是专门给 RPC 使用的 Worker 进程数
            'open_length_check' => true, // 开启 RPC 协议边界检查(根据你原本的 RPC 配置调配)
            // ... 其他 RPC 协议特定配置
        ]);

        $server->on('Receive', function ($serv, $fd, $reactor_id, $data) {
            // 在这里处理 RPC 请求逻辑
            // 可以手动调用 think-swoole 内部的 rpc 调度器,或者自己解析封装
            $serv->send($fd, "RPC Response");
        ]);

        $server->start();
    }
}

请谨慎使用此类代码。


方案二:服务拆分(生产环境最终方案)

如果你不想自己去通过自定义进程重写 RPC 的协议解析,最彻底、最稳妥的架构是将它们拆分为两个独立运行的 ThinkPHP 进程。

  1. 项目拷贝或共享代码:保持代码一份,通过不同的配置文件或环境变量来启动。

  2. Websocket 服务的配置 (config/swoole_ws.php):

    • 端口配置为 9512。

    • 关闭 RPC 关联功能。

  3. RPC 服务的配置 (config/swoole_rpc.php):

    • 主端口直接配置为 9513。

    • 关闭 Websocket 功能。

启动命令:
在服务器上开启两个终端或通过 Supervisor 启动两个独立进程:

bash

# 启动 Websocket 服务
php think swoole start --config=swoole_ws

# 启动 RPC 服务
php think swoole start --config=swoole_rpc

请谨慎使用此类代码。

注:think-swoole 默认命令行不支持 --config 参数,你可以通过定义不同的环境变量(如 ENV_SERVICE_TYPE=rpc),在标准的 config/swoole.php 中内部用 if-else 读取环境变量来返回不同的配置数组。

环境变量隔离示例 (config/swoole.php):

php

$type = env('SERVICE_TYPE', 'ws');

if ($type === 'rpc') {
    return [
        'server' => [
            'host' => '0.0.0.0',
            'port' => 9513, // 主端口直供 RPC
            'options' => ['worker_num' => 2],
        ],
        // 关闭 websocket
    ];
} else {
    return [
        'server' => [
            'host' => '0.0.0.0',
            'port' => 9512, // 主端口直供 Websocket
            'options' => ['worker_num' => 4],
        ],
    ];
}

请谨慎使用此类代码。

启动命令切换:

bash

SERVICE_TYPE=ws php think swoole start
SERVICE_TYPE=rpc php think swoole start

请谨慎使用此类代码。

使用方案二(服务拆分)是目前主流微服务架构中最安全、最容易维护的做法。

如果你打算改造,你目前的 RPC 传递数据使用的是 think-swoole 自带的 RPC 协议,还是自定义的 JSON-RPC 协议?如果是自带的,采用方案二会让你免去手动解析协议的麻烦。

技术
许可协议:  CC BY 4.0
分享

相关文章

7月 26, 2026

完美地解决 TP3 老系统数据的平滑读取

为了彻底、完美地解决 TP3 老系统数据的平滑读取,必须解决两个核心痛点: TP3 的盲猜反序列化机制(标量存原样,数组/对象存原生 serialize,同时兼容 json)。 TP3 与 TP6 的缓存前缀(Prefix)不一致。 以下是为你量身定制的终极落地解决方案,通

7月 26, 2026

thinkphp3 redis序列化和反序列化

在老系统重构迁移至 ThinkPHP 6 (TP6) 的过程中,ThinkPHP 3 (TP3) 的 Redis 序列化历史遗留问题是最核心的连环坑之一。 TP3 的 S('key', $value) 缓存方法和底层 Redis 驱动,在存储非字符串(如数组、对象)时,有一套独特的序列化行为。如果不

7月 24, 2026

Table 空间极易发生哈希冲突并溢出

既然你没有在业务中主动调用 Room,只使用了全局广播,那么这个问题就非常明确了:即使你不用房间功能,think-swoole 只要开启了 WebSocket,底层就会强行初始化并注入一个名为 Room 的驱动组件。 [1] 框架底层默认使用 table 类型来作为 Room 的存储介质。当进行全局

下一篇

think-swoole 框架底层的一个“隐藏陷阱”

上一篇

Swoole 的自定义进程(Process)

最近更新

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

热门标签

API CodeGeex Gitkraken Management Manticore Premiere Sublime Swoole ThinkPHP ThinkPHP5

目录

©2026 mdo. 保留部分权利。