代码:
global $worker;
$worker = new Worker();
Worker::$pidFile = '/dev/shm/jmworker.pid';
$worker->onWorkerStart = function(){
global $worker,$sec;
$sec = 0.5;
\Workerman\Lib\Timer::add($sec, function (){
echo '333333333333333';
//exit();
1/0;
},true);
};
// 运行worker
Worker::runAll();
遇到异常就会卡死不会退出进程,也不会重新fork一个子进程。执行exit()也不会、
比如数据库暂时无法连接,出现异常,就会导致子进程卡死不会退出,也不会重新fork一个子进程。
-------------------------------------- WORKERMAN --------------------------------------
Workerman version:4.0.19 PHP version:8.0.8
--------------------------------------- WORKERS ---------------------------------------
proto user worker listen processes status
tcp root jmworker_main none 1 [OK]
---------------------------------------------------------------------------------------
Press Ctrl+C to stop. Start success.
333333333333333DivisionByZeroError: Division by zero in /var/www/html/public/1.php:28
Stack trace:
#0 /var/www/html/vendor/workerman/workerman/Events/Event.php(167): {closure}(true)
#1 [internal function]: Workerman\Events\Event->timerCallback(-1, 1, Array)
#2 /var/www/html/vendor/workerman/workerman/Events/Event.php(195): EventBase->loop()
#3 /var/www/html/vendor/workerman/workerman/Worker.php(2430): Workerman\Events\Event->loop()
#4 /var/www/html/vendor/workerman/workerman/Worker.php(1554): Workerman\Worker->run()
#5 /var/www/html/vendor/workerman/workerman/Worker.php(1384): Workerman\Worker::forkOneWorkerForLinux(Object(Workerman\Worker))
#6 /var/www/html/vendor/workerman/workerman/Worker.php(1358): Workerman\Worker::forkWorkersForLinux()
#7 /var/www/html/vendor/workerman/workerman/Worker.php(542): Workerman\Worker::forkWorkers()
#8 /var/www/html/public/1.php(33): Workerman\Worker::runAll()
#9 {main}
Warning: EventBase::loop(): Failed to invoke event callback in /var/www/html/vendor/workerman/workerman/Events/Event.php on line 195
Warning: EventBase::loop(): Failed to invoke event callback in /var/www/html/vendor/workerman/workerman/Events/Event.php on line 195
Warning: EventBase::loop(): Failed to invoke event callback in /var/www/html/vendor/workerman/workerman/Events/Event.php on line 195
event扩展不是稳定版本?
3.0.5稳定版
root@33e87e5e5ce1:/var/www/html# php --ri event
event
Event support => enabled
Sockets support => disabled
Debug support => disabled
Extra functionality support including HTTP, DNS, and RPC => enabled
OpenSSL support => disabled
Thread safety support => disabled
Extension version => 3.0.5
libevent2 headers version => 2.1.11-stable
root@33e87e5e5ce1:/var/www/html#
你试了吗,运行一下那段代码,会不会卡死无法自动重启子进程?
有没有大佬解答一下
看看php编译参数是不是有sigchild
@2024: 使用的docker官方php镜像: docker pull php:8.0.10-fpm ,怎么看编译参数是不是有sigchild?
@2024:你运行上面这段代码会不会报错?
@6279:我没使用workman,我是用webman,php8/php7 只要编译参数里包含了sigchild的话就会出现异常,php官方有人提bug了,你可以看看php -i|grep configure
root@33e87e5e5ce1:/var/www/html# php -i|grep configure
Configure Command => './configure' '--build=x86_64-linux-gnu' '--with-config-file-path=/usr/local/etc/php' '--with-config-file-scan-dir=/usr/local/etc/php/conf.d' '--enable-option-checking=fatal' '--with-mhash' '--with-pic' '--enable-ftp' '--enable-mbstring' '--enable-mysqlnd' '--with-password-argon2' '--with-sodium=shared' '--with-pdo-sqlite=/usr' '--with-sqlite3=/usr' '--with-curl' '--with-openssl' '--with-readline' '--with-zlib' '--with-pear' '--with-libdir=lib/x86_64-linux-gnu' '--enable-fpm' '--with-fpm-user=www-data' '--with-fpm-group=www-data' '--disable-cgi' 'build_alias=x86_64-linux-gnu'
大佬,麻烦看一下包含了sigchild吗
你代码有致命错误,退出才是正常行为。workerman 在你进程出现致命错误之后就会重新 fork 一个进程的,但是你的致命错误又没有合理地处理,就会重复以上步骤。
对啊,遇到错误之后应该重新fork一个进程,但是我贴出来的代码不会重新fork一个进程。你测试了代码吗
@6279:当然试过。每次 ps 查到的子进程id都不一样了
@6279:补充一下。我用的是 React EventLoop,你可能用的是 event。刚刚对比了一下,react 的 eventloop 的 add 方法,临时想到了两个解决方法。
一、修改 Events/EventInterface.php 中的 add 方法修改为 public function add($fd, $flag, $func, array $args = []); 再将 Events/Event.php 中的 add 方法签名修改为 public function add($fd, $flag, $func, array $args = []);
二、自己在你的定时器中加上 try {} catch (Throwable $e) { echo $e->getMessage(), "\n"; },注意php7之后才可以 catch 错误,跟异常不一样的;
@6279:还是用 try catch 吧,另外一个不行
看起来是event扩展的bug,估计event扩展在php8下还没完善
@7304: 牛逼,你是修改了workerman的源代码替换成React EventLoop吗?
我剛測試了,
同樣配置下,
php7 + event + libevent2 表現正常。
php8 + event + libevent2 表現異常。
其中event和libevent2 是 相同版本的。
而且問題只有在Timer裡才會發生,
我是在FileMonitor裡,
實例化時添加1/0;
這時候php7/8 都會自動重啟。
如果在實例化添加Timer::add.....,
php7 會重啟,
php8 會一直報錯Failed to invoke event callback。
補充下:
opcache開啟關閉都試過,結果一樣。
event
Event support => enabled
Sockets support => enabled
Debug support => disabled
Extra functionality support including HTTP, DNS, and RPC => enabled
OpenSSL support => disabled
Thread safety support => disabled
Extension version => 3.0.5
libevent2 headers version => 2.1.8-stable
如果使用select模型不會出錯,只有event的timer才會異常,
感覺是event的問題。
還是使用php7.4,有高版本要求的就把event轉為select模型吧。
看起来是event扩展的bug,估计event扩展在php8下还没完善
大佬牛逼,swoole不用event扩展也会这样,不知道是不是php8的bug