背景:每天早晨九点进行微信推送,用户3-4万人
技术瓶颈:php为弱类型的语言,从头执行到尾,导致推送时长长大2个多小时
需求:减少推送时间,限定在半个小时
背景介绍完毕,开始正题:
将数据放入redis中,没有优化前直接从mysql中提取数据,使用popen开启进程指针执行相应逻辑,一下为部分代码,代码依赖关系没有全部给出,
$redis= rediscache();//链接redis
$rekey=‘key’;//在这里要使用方法生成唯一key
if($redis->exists($rekey) ) {
$redis->del($rekey);
}
通过数据的提取提取出一下形式,序列化后保存redis中
$data=array(
'user' =>array($v['userid']),
'describe' => '微笑打卡提醒 第' .ceil($day) . '天',
'thing'=> '微笑打卡',
'time'=>date('Y-m-d H:i',mktime(9, 0, 0,date('m'),date('d'),date('Y'))),
'url'=>$jump,
'epiogue'=> '点击上传微笑照片>',
);
$redis->lPush($rekey,serialize($data));
设置key的过期时间,及时的归还服务器资源
$length=$redis->lLen($rekey);
$cell= 10000;//微信每个小时推送大概的数量
if($redis->exists($rekey) && $length>0 ) {
$index=$length/$cell;
if(intval($index) > 0 ) {
$redis->expire($rekey,intval($index)*3600);
}else{
$redis->expire($rekey,3600);
}
}
进行多线程推送,根据不同数量采取不同进程
switch(intval($length)) {
case$length<200:{//一个进程
pclose(popen("php ./index.php -a 0 -b ".($length-1)." &",'r'));
$return=true;
break;
}
case$length>= 200:{//两个进程
if($length%2 == 0 ) {//是偶数
$nextStart=$length/2;
}else{//是奇数
$nextStart=floor($length/2);
}
pclose(popen("php ./index.php -a 0 -b ".($nextStart)." &",'r'));//使用后要释放进程资源
pclose(popen("php ./index.php -a ".($nextStart+1)." -b ".($length-1)." &",'r'));//使用后释放集成资源
$return=true;
break;
}
default:
$return=false;
break;
}
popen:打开一个指向进程的管道,该进程由派生指定的command命令执行而产生。使用后记得释放进程资源