PHP系列 | PDO::prepare(): send of 68 bytes failed with errno=32 Broken pipe
设计场景
1、开启Redis的键空间过期事件(键过期发布任务),创建订单创建一个过期的key,按照订单号为key,设置过期时间。
2、通过Redis的订阅模式(持久阻塞),获取到订单号进行组装。
3、Redis通过订阅模式获取到已经过期的key,把该key加入think-queue 任务队列(依赖于Redis的队列,队列配置推荐使用Redis存储消息)。
4、开启一个队列的消费守护进程,进行消费。如果消费失败,则任务队里不会自动删除
遇到的问题
cli 模式报错
[2019-11-20T14:33:25+08:00][ error ] [8]PDO::prepare(): send of 68 bytes failed with errno=32 Broken pipe
error
相关代码
class RedisSubscribe
{
public function subscribe()
{
$redis = BaseRedis::plocal();
$redis->setOption(\Redis::OPT_READ_TIMEOUT, -1);
$redis->psubscribe(array('__keyevent@1__:expired'), function ($redis, $pattern, $chan, $msg) {
Log::info('[订阅事件] 过期KEY ' . $msg);
$flag = strstr($msg,":");
if(empty($flag)){
Log::error('[订阅事件] 非法的消息类型 '.$msg);
return false;
}
$originData = explode(':',$msg);
$event_key = $originData[1]??'0';
$event_status = $originData[0]??'0';
if($event_status == RedisTaskQueue::ORDER_TIMEOUT_EVENT){
Log::info('[订阅事件] 订单超时事件 '.$event_key);
$order = PayOrderModel::get(['order_no' => $event_key]);
Log::info('[订阅事件] 订单 '.$event_key);
if ($order['status'] == 0) {
$updateData = [
'id' => $order['id'],
'status' => 2,
'notify_status' => 0,
'pay_time' => time(),
'remark' => '超时队列事件'
];
$res = PayOrderModel::update($updateData);
Log::info('[订阅事件] 更新订单 ' . json_encode($res));
}
}
});
}
}
问题就出现在以上代码中查询和更新数据库问题
$order = PayOrderModel::get(['order_no' => $event_key]);
问题分析,这里采用的Redis的订阅模式,持久性的
解决办法,通过任务队列解决
$isPushed = redis_queue(RedisTaskQueue::QUEUE_EVENT, $data);
把redis订阅服务获取到的信息,发布think-queue队列中,在队列中在进行处理数据库相关操作
第二天出错
[2019-11-21T09:12:41+08:00][ error ] [队列事件] 队列执行失败 SQLSTATE[HY000]: General error: 2006 MySQL server has gone away|#0 /home/www/web/wiot.tinywan.com/thinkphp/library/think/db/Connection.php(844): think\db\Connection->query('SELECT * FROM `...', Array, false, false)
#1 /home/www/web/www.tinywan.com/thinkphp/library/think/db/Query.php(3132): think\db\Connection->find(Object(think\db\Query))
#2 /home/www/web/www.tinywan.com/thinkphp/library/think/db/Query.php(3193): think\db\Query->find(NULL)
数据库配置开启需要断线重连(第一次出错的时候正式环境没有开启该配置参数)
// 是否需要断线重连
'break_reconnect' => false,
参考:
https://github.com/RunnerLee/fastd-eloquent/issues/5
PHP系列 | PDO::prepare(): send of 68 bytes failed with errno=32 Broken pipe的更多相关文章
- fwrite(): send of 8192 bytes failed with errno=104 Connection reset by peer
问题:fwrite(): send of 8192 bytes failed with errno=104 Connection reset by peer 问题描述 通过mysql + sphinx ...
- PHP PDO prepare()、execute()和bindParam()方法详解
每次将查询发送给MySQL服务器时,都必须解析该查询的语法,确保结构正确并能够执行.这是这个过程中必要的步骤,但也确实带来了一些开销.做一次是必要的,但如果反复地执行相同的查询,批量插入多行并只改变列 ...
- PDO::prepare
PDO::prepare — 准备要执行的SQL语句并返回一个 PDOStatement 对象(PHP 5 >= 5.1.0, PECL pdo >= 0.1.0) 说明 语法 publi ...
- Ubuntu 12.04 64bit 配置完android 5.0编译环境后出现“could not write bytes: Broken pipe.”而无法进入输入帐号密码的登陆界面
Ubuntu 12.04 64bit 配置完android 5.0编译环境后出现“could not write bytes: Broken pipe.”而无法进入输入帐号密码的登陆界面.上网问了问百 ...
- MySQL测试环境遇到 mmap(xxx bytes) failed; errno 12解决方法
查看Mysql日志 InnoDB: Initializing buffer pool, size = 128.0M InnoDB: mmap( bytes) failed; errno InnoDB: ...
- mysql报错mmap(137428992 bytes) failed; errno 12,Cannot allocate memory for the buffer pool
mysql以`systemctl start mysqld.service`的方式启动一段时间后发现突然无法启动,尝试重新启动也不能解决问题,排查问题时,先后通过`systemctl status m ...
- Cannot send, channel has already failed:
背景: 一个同事往这个队列发数据,另一个同事从这个队列取数据,进行解析. 这是昨天同事昨天消费者 消费activemq 队列,一开始有正常,运行了一段时间后,发现突然消费者变为零了.因为有监控.之后怎 ...
- org.apache.activemq.transport.InactivityIOException: Cannot send, channel has already failed
项目是使用activeMQ 发布订阅的模式,在本地测试正常,但是 放到服务器上出现这个错误: org.apache.activemq.transport.InactivityIOException: ...
- Send [1] times, still failed
com.alibaba.rocketmq.client.exception.MQClientException: Send [1] times, still failed, cost [696094] ...
随机推荐
- 英文INSURAUNCE保险INSURAUNCE词汇
世界保险INSURAUNCE 人类社会从开始就面临着自然灾害和意外事故的侵扰,在与大自然抗争的过程中,古代人们就萌生了对付灾害事故的保险思想和原始形态的保险方法.公元前2500年前后,古巴比伦王国国王 ...
- 为什么Audition CC2017扫描不了电音插件,你需要这个工具
一时兴起,我也去下载并安装了Audition的音频后期处理软件,版本是cc2017.简单熟悉了对自己声音修理外,我还想添加一点电音的效果显得洋气一些.在网上下载并安装了warves tune后,发现A ...
- Java 虚拟机 - GC 垃圾回收机制分析
Java 垃圾回收(Garbage Collection,GC) Java支持内存动态分配.垃圾自动回收,而 C++ 不支持.我想这可能也是 为什么 Java 脱胎于 C++ 的一个原因吧. GC 的 ...
- crontab定时任务不执行,单独运行sh生效
虽然已经从事运维两三年了. 但是今天写的计划任务没有执行,排除了下, 这里整理下,方便后期查看. 排除思路 1. 确保crond服务是开机自启和当前是启动的. # centos systemctl s ...
- Idea热部署插件JRebel
安装部署:https://blog.csdn.net/weixin_42831477/article/details/82229436 Jrebel不生效的原因和解决办法:https://www.cn ...
- Linux运维技术之详解任务计划(crontab命令)
crontab命令 按照预先设置的时间周期(分钟.小时.天……)重复执行用户指定的命令操作,属于周期性计划任务 (1).先来看一下/etc/crontab文件的内容: [root@localhost ...
- LoarRunner脚本录制-Port Mapping
使用LR录制脚本时经常会因为内外网访问限制,或浏览器兼容等问题,导致无法正常录制脚本. 这里简单介绍一下使用LR端口映射的方式进行脚本录制,与之前介绍的<Jmeter脚本录制--HTTP代理服务 ...
- Distance(2019年牛客多校第八场D题+CDQ+树状数组)
题目链接 传送门 思路 这个题在\(BZOJ\)上有个二维平面的版本(\(BZOJ2716\)天使玩偶),不过是权限题因此就不附带链接了,我也只是在算法进阶指南上看到过,那个题的写法是\(CDQ\), ...
- jmeter中如何引用Java
通过source()获取java文件: vars.get,获取参数type_id的值
- C++类库开发详解(转)
前言:这是一篇总结性的文章,需要有一点C++和dll基本知识的基础,在网上查阅了很多资料感觉没有一篇详细.具体.全面的dll开发介绍,我这是根据最近项目和网上资料整理出来的,并附带实例的一个总结性的文 ...