项目上有一些 php 进程需要定时扫数据库,比如每秒查询一次
现在遇到个问题,发现有些进程有时候"假死",进程还在,但是观察日志是没有继续运行了
初步判断是常驻进程和 mysql 的连接断了,比如服务器和 db 服务器网络波动等造成的
一般我们 php 查询数据库会在 new model 的时候新建连接(或是从 php-fpm 管理的连接池里获取),但是常驻进程持续持有这个连接,所以在这种断开情况下不会重新建立新的连接
1 php 检测连接状态有什么好的方案,现在知道的是 ping 或者 pdo->getAttribute(PDO::ATTR_CONNECTION_STATUS)
2 这种情况下一般如何处理 在检测后重新 new 一个?疑惑是改成不持有,每次检测前重新 new
怕进程运行时间过久,crontab 不能保持单进程运行,怕一时没执行完,每秒启一个进程"雪崩"
1
airect 2019-03-08 16:19:31 +08:00
捕捉 pdo 的异常,判断是否丢失连接,丢失的再重新连接
$message = $exception->getMessage(); return strpos($message, 'server has gone away') !== false; |
2
airect 2019-03-08 16:24:47 +08:00
第二个问题,可以在程序里做个锁,或者 crontab 里 用 flock,再就是用其他任务管理程序起。我没有认真测过,应该会有些额外的问题,你可以测试一下
|
3
flighter 2019-03-08 16:46:49 +08:00
在执行查询时,在失去连接时会 抛出 PDO 的异常,捕获该异常,判断异常是否为:'server has gone away' , 然后做重连,再执行查询
|
4
tomczhen 2019-03-08 16:54:00 +08:00 via Android
如果轮询是为了根据数据触发业务代码可以考虑改由数据库方除非事件。
在数据库本机运行 agent,拿到触发数据丢到队列,然后再来通过队列执行任务。 |
5
he583899772 2019-03-08 16:55:37 +08:00
crontab 为什么不能单进程啊,增加 lockf 机制,保证只有一个任务进程在执行啊。。。。
|
6
ashmodeus 2019-03-08 20:44:20 +08:00
1、每秒(在 mysql 连接超时时间内)都查询一次,不会丢失连接
2、判断连接是否丢失,可以在 php 服务器:netstat -lanp | grep 3306 3、连接丢失后再发起 query,会 exception:2006-MySQL server has gone away 4、重连 mysqli 有 mysqi_real_connect,使用之前 mysqli_init 创建的 link 重新连接 |
7
echo404 2019-03-09 15:26:50 +08:00
捕捉异常然后进行断线重连操作不久行了么?
|
8
JaguarJack 2019-03-09 15:49:11 +08:00 via iPhone
短线重连 还是用 mysqli 好 pdo 还要捕获异常来处理
|