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