版主請(qǐng)幫忙解惑
1.我測(cè)試的是workerman
2.實(shí)例化Worker對(duì)象,schema:http,端口號(hào)9999,設(shè)置4個(gè)進(jìn)程,端口復(fù)用參數(shù)默認(rèn)false,設(shè)置onMessage回調(diào),回調(diào)里面打印worker對(duì)象的id,然后啟動(dòng)腳本
3.在多個(gè)瀏覽器當(dāng)中訪(fǎng)問(wèn),chrome,Microsoft Edge里面訪(fǎng)問(wèn),打印出來(lái)的worker對(duì)象的id不同
4.請(qǐng)求被不同的worker進(jìn)程處理,但是沒(méi)有在workerman中沒(méi)看見(jiàn)master進(jìn)程調(diào)度worker來(lái)處理請(qǐng)求
5.那請(qǐng)求是怎么打到對(duì)應(yīng)的進(jìn)程上的
6.因?yàn)橹拔襢ork處理數(shù)據(jù)的時(shí)候都是在master進(jìn)程將任務(wù)發(fā)給子進(jìn)程,每個(gè)子進(jìn)程處理部分?jǐn)?shù)據(jù),所以對(duì)于沒(méi)看見(jiàn)master調(diào)度worker來(lái)處理請(qǐng)求感到困惑
7.master進(jìn)程接受新的連接,代碼里面沒(méi)看見(jiàn)分發(fā)給哪個(gè)進(jìn)程處理的
$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);
}
}
}
我剛剛測(cè)試了,只設(shè)置兩個(gè)進(jìn)程,然后其中一個(gè)在onMessage回調(diào)里面fclose _mainSocket (我把protected 改成了public) ,然后其中一個(gè)進(jìn)程就不能接受連接了,但是另外一個(gè)還能接受請(qǐng)求;說(shuō)明fork的時(shí)候_mainSocket被深拷貝了一份,這與我以往理解的不太一樣,我一直以為fork的話(huà)對(duì)應(yīng)source類(lèi)型的是淺拷貝,這是因?yàn)樵趛ii2使用fork多個(gè)進(jìn)程然后其中一個(gè)進(jìn)程退出了mysql鏈接對(duì)象被釋放了,其他的進(jìn)程用不了那個(gè)連接對(duì)象了,造成了這么個(gè)誤區(qū)。反過(guò)來(lái)想如果其中一個(gè)worker掛了,如果沒(méi)有深拷貝_mainSocket那么其他的進(jìn)程也不能接受新的連接了;這樣每個(gè)進(jìn)程都有自己的_mainSocket來(lái)負(fù)責(zé)接收連接,所以不存在master進(jìn)程接收到連接然后再分配給worker進(jìn)程處理對(duì)應(yīng)的請(qǐng)求,其實(shí)就是哪個(gè)進(jìn)程建立連接哪個(gè)請(qǐng)求處理。至于哪個(gè)請(qǐng)求打到哪個(gè)worker進(jìn)程上,那是操作系統(tǒng)的調(diào)度了