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

相关文章

10月 2, 2026

iOS 侧载(Sideloading)工具

AltStore 和 Sideloadly 都是目前最流行的 iOS 侧载(Sideloading)工具。 简单来说,它们的作用就是让你绕过苹果的官方 App Store,直接把第三方的 IPA 安装包(也就是 iOS 的应用安装文件)安装到你的 iPhone 或 iPad 上。 通过这两个工具,你

9月 28, 2026

注册 Chat Participant

将当前服务接入 VS Code 的 AI 聊天窗口是完全可行的。VS Code 在近期的版本中正式推出了 Chat Extensions API(github.copilot.chat),允许第三方扩展将自定义的 LLM 服务或工具注册到 Copilot Chat 面板中。 结合当前 code_ge

9月 23, 2026

php intelephense 设置 if 空格

在 VS Code 中,如果你使用的是 PHP Intelephense 插件,控制 if 关键字后面是否加空格的设置是由其内置的格式化引擎(基于 PSR-12 标准)决定的。 你可以通过修改 VS Code 的 settings.json 来配置这个行为: 1. 开启 if 后面的空格(默认/推荐

下一篇

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

上一篇

Swoole 的自定义进程(Process)

最近更新

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

热门标签

API CodeGeex Coding Cursor DeepSeek Docker Gitkraken Harness Laravel Management

目录

©2026 mdo. 保留部分权利。