当前位置: 首页 > news >正文

mysql 定位进程_多进程编程mysql超时定位

背景介绍

年前对下单中的异步出单队列进行了重构,用主进程fork子进程处理消息队列。因为可以通过控制子进程的数量,提高该消息队列的处理效率。由于一开始,都只是先上消息量不大的队列,所以都只fork了一个子进程。在生产上偶发子进程丢失mysql连接,一开始认为是mysql超时了,修改了代码,改为每次拿到新消息都示例化一个新的model去拿数据,并且在代码上加入了异常告警,后面仍出现丢失MySQL连接。后面发现是在父进程一开始就示例化了mysql连接,并且在php的tp3.2框架中,对model做了静态单例。

第一次遇到mysql超时

身为一个弱到爆的开发,我一开始认为是mysql超时了,为了快速把生产问题处理掉,就在每次拿到消息时,实例化model。并以为这样就处理掉了。

第二次遇到

过了几天,子进程丢失mysql连接的事故依然发生。这次我在代码上加入了异常告警,并且开始想着如果把这个问题处理掉。

查看mysql超时设置,发现mysql的超时时间为86400,但是生产的进程每天凌晨都会进行一次重启,显然,并不是mysql连接超时导致的。

为了找出问题,将生产的代码,写了简化版本在测试环境跑了起来。

以下为示例代码:

namespace UnionGate\Daemon;

use Home\Common\Logger;

Logger::init();

use \Org\Util\MsgQ;

class TestMysqlConnect{

private $conn;

private $model;

public function __construct()

{

$this->model = new AModel();

}

//跑这个方法运行

public function run()

{

for ($i = 0; $i < 3; $i++) {

$nPID = \pcntl_fork();//创建子进程

if ($nPID == 0) {

$this->work();

exit(0);

}

}

$n = 0;

while ($n < $this->procNum) {

$nStatus = -1;

$nPID = \pcntl_wait($nStatus);

if ($nPID > 0) {

++$n;

}

}

exit;

}

//起进程

protected function work()

{

$MsgData = "";

while (true) {

usleep(10000);

\Org\Util\MsgQ::init();

$ret = MsgQ::BlockSubsribe('testMysqlConnect', $MsgData);

if ($ret === false) {

continue;

}

$this->doSomething();

}

}

protected function doSomething()

{

}

}

use Think\Model;

class AModel extends Model{

protected $tablePrefix = 't_';

protected $tableName = 'underwrite_tmp';

protected $dbName = "underwrite";

//数据库配置

protected $connection = "UNDERWRITE_DB_CONFIG";

}

在测试环境跑了大概有12小时候之后,果然问题复现了。

这里通过netstat -anp | grep pid 命令查看进程监听的端口,发现问题发生的时候,mysql的连接已经不见了。

mysql连接关闭的原因

mysql 的server端主动关闭,(超过了超时时间)

mysql的server端主动关闭,mysql发现tcp的包时序出现了异常(即多个进程用了同一个连接)

mysql的client端关闭,资源被回收了(进程退出,变量被unset)

对应的

因为mysql的系统设置 超时时间都是86400,且进程在每天都会被重启一次,所以不是因为超时关闭的。

因为主进程后面只做对子进程的监听,并没有尝试与mysql进行连接,所以应该不是主进程和子进程复用同一个连接导致的

阅读了tp3.2的db实现的底层源码,发现tp在db连接上,做了静态单例,查了php的fork,发现php直接调用了系统的fork函数。

/* {{{ proto int pcntl_fork(void)

Forks the currently running process following the same behavior as the UNIX fork() system call*/

PHP_FUNCTION(pcntl_fork)

{

pid_t id;

id = fork();

if (id == -1) {

PCNTL_G(last_error) = errno;

php_error_docref(NULL, E_WARNING, "Error %d", errno);

}

RETURN_LONG((zend_long) id);

}

出现连接超时的原因

因为有构造函数的存在,导致一开始,父进程就有了mysql连接的静态单例,直接用了linux的fork,可以直接认为这时候子进程和主进程的变量都是一致。因而,子进程用了父进程的MySQL连接,而且,因为做了静态单例,所以不管怎么实例化,都是得到同一个mysql连接。

解决方法

主进程一进来,只做fork子进程的工作,别的连接都不处理。让子进程自己去实例化各个资源即可

相关文章:

  • 通过接口返回对方信息_真的可以通过手机号码,准确定位对方信息吗?
  • 定义string变量 需要哪些头文件_7.3 C++字符串类 | 使用string输出
  • mac下安装mysql 5.7.11卡住_Mac 安装mysql5.7 注意事项
  • mysql 5.5基本语句_MySql___(5) MySQL 必知必会
  • Mysql什么版本支持组提交_MYSQL组提交
  • mysql纵列改成恒列_php-如何将mysql表行显示为列
  • mysql ssl 2026_解决连接到 Amazon RDS for MySQL 或 Aurora 实例时的 ERROR 2026 SSL 连接错误...
  • opensuse rpm安装mysql_rpm安装MySQL
  • 顺序表的基本操作_顺序表基本操作上机实验
  • lede软路由Mysql未运行_Proxmox VE(PVE)安装LEDE/OpenWrt 软路由系统|虚拟机环境
  • mysql的awr生成语句_如何生成指定SQL语句的AWR报表
  • mysql对建表语句长度的限制_MySQL 建表字段长度的限制
  • 编译安装mysql加入services_编译安装MySQL数据库
  • win7下ado连接mysql_提示连接无法用于执行此操作_提示错误“连接无法用于执行此操作。再此上下文中可能已被关闭或者无效”...
  • java sha_原生Java实现SHA256算法
  • 分享一款快速APP功能测试工具
  • [译]前端离线指南(上)
  • avalon2.2的VM生成过程
  • canvas 五子棋游戏
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • MySQL几个简单SQL的优化
  • PHP的类修饰符与访问修饰符
  • Redis的resp协议
  • Spark VS Hadoop:两大大数据分析系统深度解读
  • Spring Cloud Feign的两种使用姿势
  • vue中实现单选
  • 初识 beanstalkd
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 试着探索高并发下的系统架构面貌
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 一文看透浏览器架构
  • 以太坊客户端Geth命令参数详解
  • #pragam once 和 #ifndef 预编译头
  • (1)(1.11) SiK Radio v2(一)
  • (3)选择元素——(14)接触DOM元素(Accessing DOM elements)
  • (day 12)JavaScript学习笔记(数组3)
  • (ibm)Java 语言的 XPath API
  • (待修改)PyG安装步骤
  • (分享)自己整理的一些简单awk实用语句
  • (附源码)spring boot网络空间安全实验教学示范中心网站 毕业设计 111454
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (九)One-Wire总线-DS18B20
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】
  • **PHP分步表单提交思路(分页表单提交)
  • .gitignore文件---让git自动忽略指定文件
  • .Mobi域名介绍
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .NET 使用配置文件
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)...
  • [ 蓝桥杯Web真题 ]-Markdown 文档解析
  • []串口通信 零星笔记