常驻 PHP 进程定时查询数据库,如何检测连接状态

2019-03-08 15:51:53 +08:00
 Immortal

情况

项目上有一些 php 进程需要定时扫数据库,比如每秒查询一次
现在遇到个问题,发现有些进程有时候"假死",进程还在,但是观察日志是没有继续运行了
初步判断是常驻进程和 mysql 的连接断了,比如服务器和 db 服务器网络波动等造成的

一般我们 php 查询数据库会在 new model 的时候新建连接(或是从 php-fpm 管理的连接池里获取),但是常驻进程持续持有这个连接,所以在这种断开情况下不会重新建立新的连接

想问下:

1 php 检测连接状态有什么好的方案,现在知道的是 ping 或者 pdo->getAttribute(PDO::ATTR_CONNECTION_STATUS)
2 这种情况下一般如何处理 在检测后重新 new 一个?疑惑是改成不持有,每次检测前重新 new

为什么不用 crontab:

怕进程运行时间过久,crontab 不能保持单进程运行,怕一时没执行完,每秒启一个进程"雪崩"

3487 次点击
所在节点    PHP
8 条回复
airect
2019-03-08 16:19:31 +08:00
捕捉 pdo 的异常,判断是否丢失连接,丢失的再重新连接
$message = $exception->getMessage();
return strpos($message, 'server has gone away') !== false;
airect
2019-03-08 16:24:47 +08:00
第二个问题,可以在程序里做个锁,或者 crontab 里 用 flock,再就是用其他任务管理程序起。我没有认真测过,应该会有些额外的问题,你可以测试一下
flighter
2019-03-08 16:46:49 +08:00
在执行查询时,在失去连接时会 抛出 PDO 的异常,捕获该异常,判断异常是否为:'server has gone away' , 然后做重连,再执行查询
tomczhen
2019-03-08 16:54:00 +08:00
如果轮询是为了根据数据触发业务代码可以考虑改由数据库方除非事件。

在数据库本机运行 agent,拿到触发数据丢到队列,然后再来通过队列执行任务。
he583899772
2019-03-08 16:55:37 +08:00
crontab 为什么不能单进程啊,增加 lockf 机制,保证只有一个任务进程在执行啊。。。。
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 重新连接
echo404
2019-03-09 15:26:50 +08:00
捕捉异常然后进行断线重连操作不久行了么?
JaguarJack
2019-03-09 15:49:11 +08:00
短线重连 还是用 mysqli 好 pdo 还要捕获异常来处理

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/542528

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX