php多进程单例模式下的 MySQL及Redis连接错误修复
来源:互联网 发布:莱昂纳德体测数据虎扑 编辑:程序博客网 时间:2024/05/20 16:40
问题描述:
前几天写了个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连接错误修复
- php redis 单例模式
- php 多进程下mysql连接 gone away
- python连接redis单例模式
- [PHP] PHP Mysql单例模式
- mySql的连接数据库操作(单例模式)
- PHP pdo单例模式连接数据库
- PHP 单例模式连接数据库
- PHP封装的一个单例模式Mysql操作类
- php 单例模式下 数据库链接的应用
- MySQL + PHP的模式在大并发压力下导致MySQL中存在大量僵死进程
- PHP编程出现的MySQL连接错误
- PHP单例模式及应用实例
- php的单例模式
- php的单例模式
- PHP的单例模式
- php的单例模式
- PHP的单例模式
- 使用HP Unified Functional Testing--检查点功能的实现
- 字节流字符流的使用
- Xcode添加静态库以及编译选项配置常见问题
- java.security.AccessControlException: access denied
- Python程序的执行原理(-)
- php多进程单例模式下的 MySQL及Redis连接错误修复
- jQuery.ajax( options )
- Oracle User和Schema的区别
- 整数中1出现的次数(从1到n整数中1出现的次数)
- Gradle——故障排除
- Effective modern C++ 条款 40:注意不同线程句柄的析构函数的行为
- Spring @Resource、@Autowired、@Qualifier的注解注入及区别
- LaTeX 文件扩展名笔记
- 项目-汉语字典总结