Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

swoole4.4.0关闭进程bug #2681

Closed
a07061625 opened this issue Jul 12, 2019 · 30 comments
Closed

swoole4.4.0关闭进程bug #2681

a07061625 opened this issue Jul 12, 2019 · 30 comments
Labels

Comments

@a07061625
Copy link

Please answer these questions before submitting your issue. Thanks!

  1. What did you do? If possible, provide a simple script for reproducing the error.
    服务启动正常,关闭进程的时候,使用\swoole_process::kill(main进程ID)关闭

  2. What did you expect to see?
    所有main,manager,task,worker进程全部关闭

  3. What did you see instead?
    所有main,manager,task,worker进程全部都没有关闭
    如下两个操作进程全部正常关闭:
    1.将swoole版本退回到4.3.2
    2.exec('kill -9 ' . main进程ID)

  4. What version of Swoole are you using (show your php --ri swoole)?
    swoole 4.4.0

  5. What is your machine environment used (including version of kernel & php & gcc) ?
    centos7.6
    php7.2.19
    gcc4.8.5

@phper08
Copy link

phper08 commented Jul 12, 2019

未能重现Bug
使用ps -ef | grep 'php test.php'观察,10秒后3个进程消失

环境:
PHP 7.3.5
Swoole 4.4.0
CentOS 7.6 单核

<?php

$server = new swoole_http_server('0.0.0.0', 60003);
$server->on('workerStart', function (swoole_http_server $server, int $worker_id) {
    if ($worker_id === 0) {
        echo $server->master_pid . "\n";
        echo $server->manager_pid . "\n";
        echo $server->worker_pid . "\n";

        swoole_timer_after(10000, function () use ($server) {
            swoole_process::kill($server->master_pid);
        });
    }
});
$server->on('request', function (swoole_http_request $request, swoole_http_response $response) {
    
});
$server->start();

@phper08
Copy link

phper08 commented Jul 12, 2019

图片

图片

@a07061625
Copy link
Author

@phper08 ...哥们,应该是我没有说清楚,我的关闭进程操作不是用swoole_timer_after这个,我这边的关闭进程脚本是类似这样的
vim close.php
<?php
$pid = 1111; //该进程ID在服务启动成功后会写入到一个pid文件,关闭服务的时候会去读取该文件
swoole_process::kill($pid);
php close.php

@a07061625
Copy link
Author

@phper08 启动和关闭操作执行脚本的用户都是同一个

@huanghantao
Copy link
Member

@a07061625 你更新到最新的代码,前几天好像修了这个bug

@phper08
Copy link

phper08 commented Jul 12, 2019

运行close.php后提示什么?或者能提供完整代码吗?

swoole_process::kill($pid, 0);
你可以看一下该进程是否存在

也许传的$pid不是master_pid

@a07061625
Copy link
Author

@phper08 
/**
* 关闭服务
*/
public function stop()
{
if (is_file($this->_pidFile) && is_readable($this->_pidFile)) {
$pid = (int)file_get_contents($this->_pidFile);
} else {
$pid = 0;
}

    $msg = ' \e[1;31m \t[fail]';
    if ($pid > 0) {
        if (\swoole_process::kill($pid)) {
            $msg = ' \e[1;32m \t[success]';
        }
        file_put_contents($this->_pidFile, '');
    }
    system('echo -e "\e[1;36m stop ' . SY_MODULE . ': \e[0m' . $msg . ' \e[0m"');
    exit();
}

//启动写入
protected function basicStart(\swoole_server $server)
{
@cli_set_process_title(Server::PROCESS_TYPE_MAIN . SY_MODULE . $this->_port);

    if (file_put_contents($this->_pidFile, $server->master_pid) === false) {
        Log::error('write ' . SY_MODULE . ' pid file error');
    }
}

@a07061625
Copy link
Author

image
@phper08

@a07061625
Copy link
Author

@huanghantao 我就是用的最新版4.4.0扩展包,从pecl下载的

@huanghantao
Copy link
Member

@a07061625 你用master分支的代码

@a07061625
Copy link
Author

@huanghantao 你是说直接用github上的master分支,不用那个pecl扩展包是么?

@huanghantao
Copy link
Member

@a07061625 对的

@a07061625
Copy link
Author

@huanghantao 我知道了,非常感谢

@a07061625 a07061625 reopened this Jul 31, 2019
@a07061625
Copy link
Author

经过本人实际测试,代码参考上述截图,swoole4.4.1,swoole4.4.2依然存在上述问题,如果本人用法有问题,欢迎指正

@a07061625
Copy link
Author

如下为swoole4.4.2时候的测试
image
image
image
image

@a07061625
Copy link
Author

@huanghantao

@a07061625
Copy link
Author

当swoole版本退回到4.3.2的时候,swoole_process::kill是正常的

@matyhtf
Copy link
Member

matyhtf commented Aug 1, 2019

注册workerExit回调,清理定时器,4.4 版本的退出机制更安全了,会检测是否有 事件和定时器,否则会持续等待,超时后会强制退出。

@shenzhe
Copy link
Member

shenzhe commented Aug 3, 2019

可以配置max_wait_time 这个选项来缩短强制退出的时间,默认是30s.
不过还是建议等事件或定时器完成后安全退出

@a07061625
Copy link
Author

@matyhtf 好的,谢谢峰哥,我确实没有注册workerExit回调,我马上去测试下

@a07061625
Copy link
Author

@shenzhe 我设置了max_wait_time 为60秒的,
image

@a07061625
Copy link
Author

@matyhtf 峰哥,我刚才测试了下,貌似还是不行呢?能指导下是哪里出问题了么?

@a07061625
Copy link
Author

image
image
image

@a07061625
Copy link
Author

image

@a07061625
Copy link
Author

其他的代码我都没有变动,只是增加了上述代码

@shenzhe
Copy link
Member

shenzhe commented Aug 6, 2019

配置短点,比如2秒

@a07061625
Copy link
Author

@shenzhe 和配置的等待时间没有关系,不管配置多长时间,实际情况是在swoole4.4.3版本,swoole_process::kill以后进程一直存在,我配置的六十秒,但是过了差不多十分钟后,依然存在,改成三十秒还是一样的,并没有杀死进程

@NHZEX
Copy link

NHZEX commented Aug 14, 2019

@shenzhe 和配置的等待时间没有关系,不管配置多长时间,实际情况是在swoole4.4.3版本,swoole_process::kill以后进程一直存在,我配置的六十秒,但是过了差不多十分钟后,依然存在,改成三十秒还是一样的,并没有杀死进程

说明仍然有资源没被释放。
我之前也swoole升级时也遇到这个问题:

  1. 定时器关闭,连接池释放,销毁事件监听,尝试退出协程。
  2. 如果在自定义进程内,则监听信号,完成上述清理操作。

@a07061625
Copy link
Author

在swoole4.4.6版本中,该问题已经被解决,其他版本未测试

@a07061625
Copy link
Author

@matyhtf @shenzhe @NHZEX

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants