// Get column mapping for UI
foreach(static::getUiColumns() as $column_name => $prop){
!isset($worker->{$prop}) && $worker->{$prop} = 'NNNN';
$prop_length = \strlen($worker->{$prop});
$key = '_max' . \ucfirst(\strtolower($column_name)) . 'NameLength';
static::$$key = \max(static::$$key, $prop_length);
}
// Listen.
if (!$worker->reusePort) {
$worker->listen();
}
关闭端口复用疑问:
1、“服务端套接字”为什么不直接通过forkWorkersForLinux() 在子进程创建;要在主进程创建“服务端套接字”,通过子进程复制父进程mainSocket 呢?
请问是因为,关闭端口复用情况下;主进程单独监听端口,不会报出“端口被占用错误”?
// Remove other listener.
foreach(static::$_workers as $key => $one_worker) {
if ($one_worker->workerId !== $worker->workerId) {
$one_worker->unlisten();
unset(static::$_workers[$key]);
}
}
2、创建新的子进程监听服务端口,取消其它“服务端套接字”;这个是什么意思?创建出来的子进程,不应该只复制master的“服务端套接字”,为什么还要unlisten()?
\stream_context_set_option($this->_context, 'socket', 'so_reuseport', 1);
3、reusePort = true , 我即使注释掉上面这个代码,多个子进程未提醒“端口占用问题”。是因为我本地WSL linux 版本高的原因?
$socket = \socket_import_stream($this->_mainSocket);
\socket_set_option($socket, \SOL_SOCKET, \SO_KEEPALIVE, 1);
4、SO_KEEPALIVE 连接复用,这个配置参数指的是长连接,实际体现是什么样子?
1、如果没开reusePort,进程A监听某端口后,进程B就无法再监听这个端口,否则会报错
address already in use
。所以需要主进程监听某个端口,通过fork来实现多个进程监听同一端口
2、主进程为了业务需要可能执行了多个端口监听,主进程fork出子进程后,子进程继承了主进程的监听,其实子进程不需要所有的监听,所以会关闭不需要的监听,只保留一个属于自己的监听
3、WSL没试过,不清楚。一般情况linux系统在没开reusePort的情况下不允许重复监听端口
4、SO_KEEPALIVE 是一个TCP选项,当连接空闲一段时间后TCP底层会发送keepalive报文。SO_KEEPALIVE开启后可以用来检测死连接,避免死连接占用服务器资源。如果把发送keepalive报文间隔缩短,也可以用来tcp保活,防止连接长时间不通讯被路由节点或者防火墙等断开。
4、SO_KEEPALIVE 是一个TCP选项,这个选项我注释掉。
56182:浏览器客户端端口
19000: Workerman http端口
我注释掉“SO_KEEPALIVE”选项,Wireshark 捕获日志,发现 “TCP Keep-Alive” 来自客户端发出,Workerman 作出回应。这是系统配置默认会出现,还是因为客户端主动发起呢??
“SO_KEEPALIVE”选项生效后,连接处于空闲状态,“TCP Keep-Alive” 数据包是由客户端还是服务器发送出来呢???
5、Events 命名空间下Swoole 循环事件,\Workerman\Events\EventInterface::add()
请问为什么不直接通过 Swoole\Event::isset(mixed $fd, int $events = SWOOLE_EVENT_READ | SWOOLE_EVENT_WRITE): bool ,这种方式判断FD是否已经注册读写事件,然后作出事件“读/写” 修改操作??
TCP Keep-Alive 2个端都可以发,SO_KEEPALIVE网上有很详细的说明,可以自行查阅。
Swoole 循环事件不是我写的,是其他人发的pr,我没仔细研究过
感谢!