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);
}
看代码知道,我根据待处理的数据量启动最多10个的worker去处理数据,每个worker是一个进程,但跑起来后遇到两个错误:
一个是mysql的:MySQL server has gone away
另一个是redis的:Uncaught exception ‘RedisException’ with message ‘read error on connection’
原因:
出现MySQL server has gone away 常见的原因就是连接时间超过了mysql设置的wait_timeout值,这时mysql会主动关掉连接,默认是8小时。但是我是启动脚本就出现这个错误,而且使用连接前都先做了ping,不可能是连接超时了,又看了mysql官网对这个错误可能原因的说明(原文)里面有这么一句:
You can also encounter this error with applications that fork child processes, all of which try to use the same connection to the MySQL server. This can be avoided by using a separate connection for each child process.
很多公司代码在创建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也使用同样方法解决问题
php多进程单例模式下的 MySQL及Redis连接错误修复的更多相关文章
- redis连接错误3种解决方案System Error MISCONF Redis is configured to save RDB snapshots
redis连接错误System Error MISCONF Redis is configured to save RDB snapshots, but XX 情况1解决办法: 由于强制停止red ...
- Linux下开启MySQL的远程连接
今天在用客户端工具远程连接mysql的时候,连接不上,以为是防火墙,关了防火墙后依然打不开,后开在网上查了下原来mysql基于安全考虑root账户一般只能本地访问,但是在开发过程中可能需要打开root ...
- windows linux 下安装mysql 报1045 等错误
曾经在windows 下安装mysql 没怎么出现过问题.而在linux下安装的时候出现了一些问题,昨天在windows 安装的时候也出现了1045 错误.就个人经历来看这个问题就是 root用户pa ...
- linux搭建的LNMP环境下的mysql授权远程连接
用phpstudy搭建的lnmp环境下mysql授权远程连接 简单高效 这是因为mysql 里的优先级不是所有人(提前检查防火墙是关闭状态)1.使用phpstudy安装的mysql没有放置到可以直接调 ...
- Linux CentOs 下 安装 mysql nginx redis
SCP 的使用 来源于: https://blog.csdn.net/qq_30968657/article/details/72912070 scp [参数] <源地址(用户名@IP地址或主机 ...
- linux下遇见mysql启动报2002错误解决办法
前言:目前问题解决了,但是仍不知道是什么原因造成的,在出现问题前安装uWSGI后,mysql就出现这个问题的,哪位大侠说说这是怎么回事? 正文:Linux 下 Mysql error 2002 错误解 ...
- 亚马逊EC2 ubuntu下安装mysql远程无法连接问题o
无法远程的原因有很多,我今天遇到的问题是通过navicat无法远程连接我在EC2上创建的实例. 1.通过命令" netstat -an|grep 3306 "检查一下3306端口对 ...
- CentOS下WDCP下的MYSQL开启远程连接
1.首先要在防火墙开启3306端口访问 2.然后做如下操作 如何开启MySQL的远程帐号-1)首先以 root 帐户登陆 MySQL 在 Windows 主机中点击开始菜单,运行,输入"cm ...
- Linux下设置mysql允许远程连接
最近在Linux上安装了Mysql,然后在Windows环境下通过Navicat来连接时,出现报错:1045 Access denied for user 'root'@'XXX' (using pa ...
随机推荐
- ArrayList的去重问题
面试被问及arraylist的去重问题,现将自己想的两种解决方案写在下面 /** * Description: * ClassName:Uniq * Package:com.syd.interview ...
- DQL-分组查询
一.语法 select 分组函数,分组后的字段 from 表 [ where 筛选条件] group by 分组的字段[having 分组后的筛选][order by 排序列表] 例如 S ...
- C# Console类的方法使用总结
Console类表示控制台应用程序的标准输入流.输出流和错误流. 此类不能被继承,而在Java中,类似的功能则由System.in和System.out来实现了. 一 输出到控制台 输出到控制台就是把 ...
- JavaScript字符串的处理方法
1.字符方法charAt()和charCodeAt();这两个方法都接收一个参数 var stringValue = "hello world"; stringValue.char ...
- ubuntu18.04安装搜狗输入法
首先,安装Fcitx输入框架 sudo apt install fcitx 其次,上搜狗输入法官网下载Linux版本搜狗输入法(32位和64位根据自己情况,在虚拟机上用浏览器下载即可 然后进入相应的下 ...
- Oracle登录失败:监听程序当前无法识别连接描述符中请求的服务
Oracle11g下载地址:https://pan.baidu.com/s/1p3RwLUTAl1Ys4yXmXJ3OVQ 安装步骤视频链接:https://pan.baidu.com/s/1c0FC ...
- canvas绘制圆角头像
如果你想绘制的网页包含一个圆弧形的头像的canvas图片,但是头像本身是正方形的,需要的方法如下:首先, 拿到头像在画布上的坐标和宽高:(具体怎么获取不在此做具体介绍) 使用canvas绘制圆弧动画 ...
- jQuery DOM/属性/CSS操作
jQuery DOM 操作 创建元素 只需要把DOM字符串传入$方法即可返回一个 jQuery 对象 var obj = $('<div class="test">&l ...
- thinkPHP5.0框架验证码调用及点击图片刷新简单实现方法
这篇文章主要介绍了thinkPHP5.0框架验证码调用及点击图片刷新简单实现方法,结合简单示例形式分析了thinkPHP5框架验证码相关配置.后台验证.前台刷新等操作技巧,学习thinkphp源码的朋 ...
- WEB中需求分析应该考虑的问题
一. 针对用户群体要考虑因素 1.用户年龄 2.选择素材 3.网站布局 4.颜色搭配 5. 用户体验及动效 6.功能便捷 用户需求.用户兴趣爱好.性格.职业.教育水平高低.消费观念.PC端和移动端哪一 ...