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

  1. //跑完数据后休息60秒
  2. $sleepTime = 60;
  3. $maxWorker = 10;
  4. while (true) {
  5. $htmlModel = new DetailHtmlModel();
  6. //新抓取的html数目
  7. $count = $htmlModel->getCount(array(
  8. array('status', '=', DetailHtmlModel::STATUS_UNDEAL)
  9. ));
  10. if ($count > 0) {
  11. //将抓取的html数据放入队列
  12. Queue::putHtmlData();
  13. }
  14. $queueLength = Queue::getHtmlQueueLength();
  15. if ($queueLength > 0) {
  16. //启动的worker数目,限制启动的个数
  17. $workerCount = min($maxWorker, ceil($queueLength / 10));
  18. runWorker($workerCount);
  19. $sleepTime = 60;
  20. } else {
  21. //无数据的话每次多停5秒
  22. $sleepTime += 5;
  23. }
  24. unset($htmlModel);
  25. sleep($sleepTime);
  26. }

看代码知道,我根据待处理的数据量启动最多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:

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

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

php多进程单例模式下的 MySQL及Redis连接错误修复的更多相关文章

  1. 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 ...

  2. Linux下开启MySQL的远程连接

    今天在用客户端工具远程连接mysql的时候,连接不上,以为是防火墙,关了防火墙后依然打不开,后开在网上查了下原来mysql基于安全考虑root账户一般只能本地访问,但是在开发过程中可能需要打开root ...

  3. windows linux 下安装mysql 报1045 等错误

    曾经在windows 下安装mysql 没怎么出现过问题.而在linux下安装的时候出现了一些问题,昨天在windows 安装的时候也出现了1045 错误.就个人经历来看这个问题就是 root用户pa ...

  4. linux搭建的LNMP环境下的mysql授权远程连接

    用phpstudy搭建的lnmp环境下mysql授权远程连接 简单高效 这是因为mysql 里的优先级不是所有人(提前检查防火墙是关闭状态)1.使用phpstudy安装的mysql没有放置到可以直接调 ...

  5. Linux CentOs 下 安装 mysql nginx redis

    SCP 的使用 来源于: https://blog.csdn.net/qq_30968657/article/details/72912070 scp [参数] <源地址(用户名@IP地址或主机 ...

  6. linux下遇见mysql启动报2002错误解决办法

    前言:目前问题解决了,但是仍不知道是什么原因造成的,在出现问题前安装uWSGI后,mysql就出现这个问题的,哪位大侠说说这是怎么回事? 正文:Linux 下 Mysql error 2002 错误解 ...

  7. 亚马逊EC2 ubuntu下安装mysql远程无法连接问题o

    无法远程的原因有很多,我今天遇到的问题是通过navicat无法远程连接我在EC2上创建的实例. 1.通过命令" netstat -an|grep 3306 "检查一下3306端口对 ...

  8. CentOS下WDCP下的MYSQL开启远程连接

    1.首先要在防火墙开启3306端口访问 2.然后做如下操作 如何开启MySQL的远程帐号-1)首先以 root 帐户登陆 MySQL 在 Windows 主机中点击开始菜单,运行,输入"cm ...

  9. Linux下设置mysql允许远程连接

    最近在Linux上安装了Mysql,然后在Windows环境下通过Navicat来连接时,出现报错:1045 Access denied for user 'root'@'XXX' (using pa ...

随机推荐

  1. tomcat启动后报错Bad version number in .class file (unable to load class oracle.jdbc.OracleDriver)

    对于tomcat启动后报错: 错误原因:tomcat使用的jdk和eclipce的编译用的jdk版本不同. 解决办法: 1.首先确定tomcat的jdk版本: 2.点开tomcat查看jdk版本. 使 ...

  2. SharePoint2013之双语切换

    最近遇到个项目需要用SharePoint2013实现双语.看了篇老外的博客,经过项目经理的指点,终于算是搞定了(后面解释为什么说是"算是"). 在SharePoint2013中不像 ...

  3. react系列(五)在React中使用Redux

    上一篇展示了Redux的基本使用,可以看到Redux非常简单易用,不限于React,也可以在Angular.Vue等框架中使用,只要需要Redux的设计思想的地方,就可以使用它. 这篇主要讲解在Rea ...

  4. 转:30分钟学会如何使用Shiro

    引自:http://www.cnblogs.com/learnhow/p/5694876.html 本篇内容大多总结自张开涛的<跟我学Shiro>原文地址:http://jinniansh ...

  5. Java并发编程:浅析几种线程安全模型 [转]

    多线程编程一直是老生常谈的问题,在Java中,随着JDK的逐渐发展,JDK提供给我们的并发模型也越来越多,本文摘取三例使用不同原理的模型,分析其大致原理.目录如下: 1.COW之CopyOnWrite ...

  6. Jqgrid利用正则匹配表达式正确移除html标签

    在使用JqGrid表格插件过程中,遇到一个问题:后台取出来的字段是带有Html标签的,于是将内容填充到表格之后,带有的html标签会把表格撑开或者每一行的内容显示不统一,导致非常难看,就像下图所示: ...

  7. nuxt 优化项:禁用js的预加载

    这里有个nuxt和vue不同的地方,这个地方很有意思,官方的中文文档说得蜜汁自信 ------------------------------- In production, nuxt.js uses ...

  8. 使用boost.asio实现网络通讯

    #include <boost/asio.hpp> #define USING_SSL //是否加密 #ifdef USING_SSL #include <boost/asio/ss ...

  9. 链表--数据结构与算法JavaScript描述(6)

    链表 概念 链表是由一组节点组成的集合. 每个节点都使用一个对象的引用指向它的后继. 指向另一个节点的引用叫做 链. 许多链表的实现都在链表最前面有一个特殊节点,叫做头节点. 链表的尾元素指向一个nu ...

  10. Lingo基本操作

    目录 Lingo基本操作 前言 一.Lingo基本运算符 1.1 算术运算符 1.2 逻辑运算符 1.3 关系运算符 二.函数 2.1 标准数学函数 2.2 集循环函数 三.待更新 Lingo基本操作 ...