关于workerman的工作模式

1024

问题描述

workerman的工作模式不就是swoole的单线程模式(SWOOLE_BASE)吗?
swoole的文档中写道(https://wiki.swoole.com/wiki/page/353.html):
每个Worker进程同时承担了Process模式下Reactor线程和Worker进程两部分职责
其实就是reactor模型的单线程模式,对吧?在reactor模型的单线程模式的某个线程中,如果回调函数或者叫事件处理函数十分耗时,那么就无法执行到epoll_wait,于是无法立即处理后面的事件

情况1:设置workerman的count=1,对应于一个reactor单线程模式。那么只有一个逻辑CPU在处理所有请求,如果一个请求执行耗时操作中,那么下一个请求就进不来;

情况2:设置workerman的count=n(>1),对应于多个reactor单线程模式。假设某个worker进程(该进程是单线程的)的回调函数执行了耗时的操作,但是下一个请求可以负载均衡分配到其它的worker进程(该进程是单线程的),还是可以立即响应的。我的理解是对的吧?

代码

情况1:count=1,回调函数handle_message中sleep(100)

<?php
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

$global_uid = 0;

// 当客户端连上来时分配uid,并保存连接,并通知所有客户端
function handle_connection($connection)
{
    global $text_worker, $global_uid;
    // 为这个连接分配一个uid
    $connection->uid = ++$global_uid;
    echo "[{$global_uid}]连接成功\n";
}

// 当客户端发送消息过来时,转发给所有人
function handle_message(TcpConnection $connection, $data)
{
    ...
    sleep(100);
}

// 当客户端断开时,广播给所有客户端
function handle_close($connection)
{
    ...
}

// 创建一个文本协议的Worker监听2347接口
$text_worker = new Worker("text://0.0.0.0:2347");

// 只启动1个进程,这样方便客户端之间传输数据
$text_worker->count = 1;

$text_worker->onConnect = 'handle_connection';
$text_worker->onMessage = 'handle_message';
$text_worker->onClose = 'handle_close';

Worker::runAll();

情况2:count=4,回调函数handle_message中sleep(100)

<?php
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

$global_uid = 0;

// 当客户端连上来时分配uid,并保存连接,并通知所有客户端
function handle_connection($connection)
{
    global $text_worker, $global_uid;
    // 为这个连接分配一个uid
    $connection->uid = ++$global_uid;
    echo "[{$global_uid}]连接成功\n";
}

// 当客户端发送消息过来时,转发给所有人
function handle_message(TcpConnection $connection, $data)
{
    ...
    sleep(100);
}

// 当客户端断开时,广播给所有客户端
function handle_close($connection)
{
    ...
}

// 创建一个文本协议的Worker监听2347接口
$text_worker = new Worker("text://0.0.0.0:2347");

// 启动4个进程
$text_worker->count = 4;

$text_worker->onConnect = 'handle_connection';
$text_worker->onMessage = 'handle_message';
$text_worker->onClose = 'handle_close';

Worker::runAll();
751 1 1
1个回答

walkor

对,workerman的工作模式类似swoole的SWOOLE_BASE。
情况1:是的
情况2:看情况,如果是长连接应用,假设客户端A和客户端B都连在同一个进程上,当进程处理客户端A的的请求时,客户端B发的请求仍然会发到这个进程上。如果是短连接应用,假设进程A在处理客户端A的请求,这时客户端B发起连接,这时候客户端B会连接到其它空闲的进程上,请求也会发给空闲的进程。

年代过于久远,无法发表回答
🔝