php多进程单例模式下的 MySQL及Redis连接错误修复

前几天写了个php常驻脚本,主要逻辑如下

//跑完数据后休息60秒
$sleepTime = 60;
$maxWorker = 10;
while (true) {
$htmlModel = new DetailHtmlModel();
//新抓取的html数目
$count = $htmlModel->getCount(array(
array('status', '=', DetailHtmlModel::STATUS_UNDEAL)
));
if ($count > 0) {
//将抓取的html数据放入队列
Queue::putHtmlData();
}
$queueLength = Queue::getHtmlQueueLength();
if ($queueLength > 0) {
//启动的worker数目,限制启动的个数
$workerCount = min($maxWorker, ceil($queueLength / 10));
runWorker($workerCount);
$sleepTime = 60;
} else {
//无数据的话每次多停5秒
$sleepTime += 5;
}
unset($htmlModel);
sleep($sleepTime);
}

看代码知道,我根据待处理mysql数据库命令大全的数据量启动html文件怎么打开最多10个的worker去处理数据,数据结构每个worker是一个进程,html标签属性大全但跑起来后遇到两个错误

一个是mysql的:MySQL server has gone away

另一个是redis的:Uncaught exception ‘Redishtml网页制作Exception’ with message ‘read error onhtml个人网页完整代码 connection’

原因:


出现MySQL server h数据库原理及应用as gone away 常见的原因mysql索引就是连接时间超过了mysql设置的wait_timeout值,这时mysql数据库增删改查基本语句会主动关掉连接,默认是8小时mysql面试题。但是我是启动脚本就出现这个错误,而且使用连接前都先做了ping,不可能是连接超时了,又看了mysql面试题mysql官网对这个错误可能原因的说明数据库系统的核心是里面有这么数据库设计一句:

You can a数据漫游是什么意思lso encounter this error with applications that fork child processes, all of which try to use the same connection thtml文件怎么打开o the MySQL server. T数据库设计his can be avoided数据漫游是什么意思 by using a separate connection for each chtml简单网页代码hild procehtml标签ss.

很多公司代码在创建mysql和redis的连接实例时,采用的都是单例模式,我们也一样。也就是说无论外部new了多少实例,只要句柄存在就会被返回,数据库系统概论第五版课后答案而不是重新创建连接实例。刚好我又启动了多个进程去处理数据,然后每个进程又使用同一个连接实例,就导致了报错

解决办法:


通常只有在cli运行模式下才有可能出现超时的情况,所以在构建mysql单例句柄的key时使用数据库系统工程师​getmypid()​​加入进程id,这样就能把每个进程使用的连接实例分数据库是什么隔开

mysql:

private static function _getHandleKey($params) {
//解决多进程会保持同一个连接的错误
if (PHP_SAPI === 'cli') {
$params['pid'] = getmypid();
}
ksort($params);
return md5(implode('_' , $params));
}

redis也使用同样方法解决问题