版主请帮忙解惑
1.我测试的是workerman
2.实例化Worker对象,schema:http,端口号9999,设置4个进程,端口复用参数默认false,设置onMessage回调,回调里面打印worker对象的id,然后启动脚本
3.在多个浏览器当中访问,chrome,Microsoft Edge里面访问,打印出来的worker对象的id不同
4.请求被不同的worker进程处理,但是没有在workerman中没看见master进程调度worker来处理请求
5.那请求是怎么打到对应的进程上的
6.因为之前我fork处理数据的时候都是在master进程将任务发给子进程,每个子进程处理部分数据,所以对于没看见master调度worker来处理请求感到困惑
7.master进程接受新的连接,代码里面没看见分发给哪个进程处理的
$worker = new \Workerman\Worker('http://0.0.0.0:9999');
$worker->count = 4;
$worker->onMessage = function (\Workerman\Connection\TcpConnection $tcpConnection,\Workerman\Protocols\Http\Request $request){
$id = $tcpConnection->worker->id;
$tcpConnection->send("$id");
};
以下是workerman接受连接的源码
public function acceptConnection($socket)
{
// Accept a connection on server socket.
\set_error_handler(function(){});
$new_socket = \stream_socket_accept($socket, 0, $remote_address);
\restore_error_handler();
// Thundering herd.
if (!$new_socket) {
return;
}
// TcpConnection.
$connection = new TcpConnection($new_socket, $remote_address);
$this->connections[$connection->id] = $connection;
$connection->worker = $this;
$connection->protocol = $this->protocol;
$connection->transport = $this->transport;
$connection->onMessage = $this->onMessage;
$connection->onClose = $this->onClose;
$connection->onError = $this->onError;
$connection->onBufferDrain = $this->onBufferDrain;
$connection->onBufferFull = $this->onBufferFull;
// Try to emit onConnect callback.
if ($this->onConnect) {
try {
\call_user_func($this->onConnect, $connection);
} catch (\Exception $e) {
static::stopAll(250, $e);
} catch (\Error $e) {
static::stopAll(250, $e);
}
}
}
我刚刚测试了,只设置两个进程,然后其中一个在onMessage回调里面fclose _mainSocket (我把protected 改成了public) ,然后其中一个进程就不能接受连接了,但是另外一个还能接受请求;说明fork的时候_mainSocket被深拷贝了一份,这与我以往理解的不太一样,我一直以为fork的话对应source类型的是浅拷贝,这是因为在yii2使用fork多个进程然后其中一个进程退出了mysql链接对象被释放了,其他的进程用不了那个连接对象了,造成了这么个误区。反过来想如果其中一个worker挂了,如果没有深拷贝_mainSocket那么其他的进程也不能接受新的连接了;这样每个进程都有自己的_mainSocket来负责接收连接,所以不存在master进程接收到连接然后再分配给worker进程处理对应的请求,其实就是哪个进程建立连接哪个请求处理。至于哪个请求打到哪个worker进程上,那是操作系统的调度了
mysql的连接作为的是客户端连接,和作为服务端的连接在处理上是不同的,socket server在这个情况下是交给系统内核来进行处理分配的,如果仅仅是浅拷贝,达不到这个效果,毕竟是不同进程
感谢