Closed xueron closed 6 years ago
Yes, thanks guy.
Tips, 亲测确实如此。 @JanHuang 或许可以加在文档提示大家。来源见http://php.net/manual/zh/pdo.connections.php 下面的评论。
if parent process made a mysql connection, use $swoole_prcess->exit(0); in child process, will cause parent's connection lost.
If you want to keep connection after fork exit, you can kill with SIGKILL forked process.
eg.
class WorkerProcess extends Process
{
protected $pid;
protected $timeoutTimerId;
protected $worker_process;
public function handle(swoole_process $swoole_process)
{
$this->pid = getmypid();
$this->worker_process = $swoole_process;
// use sigkill to close process
register_shutdown_function(function () {
swoole_process::kill(getmypid(), SIGKILL);
});
}
}
@xueron 是哦,还真是这样子。我在完善文档这块也加上这个说明。感谢提醒。😆
public function handle(swoole_process $swoole_process)
{
parent::handle($swoole_process);
// use sigkill to close process
register_shutdown_function(function () {
swoole_process::kill(getmypid(), SIGKILL);
});
// 重新注入Cache服务
$config = config()->get('cache');
app()->add('cache', new CachePool($config));
unset($config);
// 重新注入DB服务
$config = config()->get('database', []);
app()->add('phalcon_db', new DatabasePool($config));
unset($config);
// 激活连接池
foreach (app() as $service) {
if ($service instanceof PoolInterface) {
$service->initPool();
}
}
}
@JanHuang 容器里面的连接池对象也得重新new一个出来。对redis的连接也是这个情况。测试许久,目前这样能够既保证每个子进程都是新建数据库和redis的连接,退出后也不会影响父进程自己的连接。
@xueron 可以,很感谢你的提醒。方便留个联系方式?方便学习
@JanHuang xueron#xueron.com
子进程会复制父进程所有的文件描述符,并且在子进程退出的时候全部关闭。上述方案也不是非常的稳定。
我测试最稳定的办法是在new一个子进程并且start()之后,立刻调用:
// 激活连接池
foreach (app() as $service) {
if ($service instanceof PoolInterface) {
$service->initPool();
}
}
在父进程里面全部重新连接一次。这样最可靠。
我在写一个定时任务管理器,思路是写一个任务管理进程manager process,通过server的addProcess()进行管理,然后定时按需fork工作子进程,完成定时任务后退出。管理进程和工作进程都会用到数据库连接。上述方案目前测试可行了。
感谢提供思路,我会到实测一次,模拟场景
Add a parament to force connect when initPool() called.
Scene: When I start a new process from a worker, a taskworker, or a server managed user process, the new process will copy parent's connections, even if I call initPool() at the beginning of process callback. It's not OK ~
So I make such fix, to use the same way used in onWorkerStart().