shell脚本作为保证PHP脚本不挂掉的守护进程实例分享


Posted in PHP onJuly 15, 2013

前几天开始跑一份数据名单,名单需要提供用户名、是否有手机号、是否有邮箱,用户名单我轻易的获取到了,但是,用户名单有2000w之多,并且去检测用户是否有手机号、是否有邮箱必须得通过一个对外开放的安全接口一个一个用户去请求,然后分析返回值才能知道。

下面是我处理的方案:
1、将2000w名单保存到临时数据表
2、用PHP程序每次从该表获取500个用户,检测完后生成SQL update原纪录
3、为了防止PHP程序突然断掉,用shell脚本每隔1分钟检测,PHP挂掉了则重启
我使用shell脚本作为守护进程的原因是,手机与邮箱的检测接口速度慢,不可能在1~2天将2000w用户检测完。

方案详细:
1、临时保存用户名单表users,表结构如下:

CREATE TABLE `users` ( 
  `account` varchar(50) COMMENT '用户名', 
  `has_phone` tinyint(3) unsigned NOT NULL default '0' COMMENT '是否有手机号', 
  `has_email` tinyint(3) unsigned NOT NULL default '0' COMMENT '是否有邮箱', 
  `flag` tinyint(3) unsigned  NOT NULL default '0' COMMENT '标志位', 
  PRIMARY KEY  (`account`), 
  KEY `flag` (`flag`) 
 ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='名单表';

我先将2000多w用户名导入到这个临时表,has_phone与has_email这二个字段默认都是0(没有),标志位flag说明该用户是否已经检测完。
下面是一部分表数据:
9873aaa,0,0,0
adddwwwd876222,0,0,0
testalexlee,0,0,0
codejia.net,0,0,0
haohdouywaa21,0,0,0
 
2、PHP脚本check_users.php
将 用户名单导入到表之后,再写一个简单的PHP脚本,思路是这样的:每次循环从表取flag=0的500个用户,然后请求接口判断用户是否有手机号、邮箱, 生成一条SQL,保存到一个SQLS数组里,等500个用户全部检测完了之后,循环SQLS数组,更新表里这500个名单,并将flag标志位设置为1, 表示已经检测完,下次就不获取了。
由于PHP脚本代码较长,这里分享下简单的代码说明:
<?php 
class Users{ 
    private $data; 
    private $sqls; 
    private $nums;         //判断是否有500用户 
    private $total_nums;   //当前已经检测完的用户数量     //每次取500个用户 
    private function getUsers(){...} 
    //检测这500个用户并生成SQL 
    private function checkUserInfo(){...} 
    //更新这500个用户 
    private function updateUserInfo(){...} 
    //运行 
    public function run(){ 
        $flag = true; 
        while($flag){ 
             if($this->nums != 500){ $flag = false; } 
             if($this->total_nums == 10000){  
                exit(0); //跑完1w个用户就退出,由守护进程启动 
             } 
             $this->getUsers(); 
             $this->checkUserInfo(); 
             $this->updateUserInfo(); 
             sleep(1); //跑完500用户休息1秒,保护用户检测接口      
         } 
    } 
} 
$user = new Users(); 
$user->run(); 
?>

上面是简洁版的PHP脚本,大概意思到了,刚开始的版本是没有$total_nums这个变量,是因为刚开始跑这个脚本的时候,发现只跑完了4w多条脚本就挂球了,后来一看,是因为连接数据库没连上,脚本一直挂在那里。加上这个变量也无法解决这个问题,只是在每次跑完1w个用户之后,PHP脚本退出,再由下面的shell脚本重新启动。

3、shell脚本作为守护进程
我把这个shell脚本加到了crontab里边,每隔1分钟执行一次,这个shell脚本很简单,检测check_users.php是否存在进程id,如果存在,则说明PHP脚本还在运行,shell脚本不做任何操作;如果不存在,则说明PHP脚本已经exit(0)跑完了1w用户退出了,那么shell脚本启动该脚本,进入下一个1w用户名单的检测。
上面我有讲到,如果PHP脚本在连接数据库的时候,无法连接上的时候,PHP会一直挂球在那里,无法退出了。我在shell脚本里加了一个时间检测,当PHP脚本进程存在的时候,计算已经存在了多长时间,如果超过了我预想的时间,则将PHP脚本kill掉,再重启。

开头的举例数据,结果类似如下:
testalexlee,1,0,1
codejia.net,0,0,1
haohdouywaa21,1,1,1
9873aaa,0,1,1
adddwwwd876222,1,0,1

说在最后:以上用户名单数据只是举个栗子,不要太认真,2000w数据,我估计要跑一段时间了,因为检测接口比较慢,接口在接到请求后还要连表,查表,再返回。其实,最好的方法还是直接从接口请求的表拉一份名单出来,再用shell命令处理下很快就有结果了,可是在公司就是这样,有些东西不开放的,你懂的~~~

PHP 相关文章推荐
php checkbox复选框值的获取与checkbox默认值输出方法
May 15 PHP
PHP 5.3.1 安装包 VC9 VC6不同版本的区别是什么
Jul 04 PHP
php中显示数组与对象的实现代码
Apr 18 PHP
php数组函数序列之array_unique() - 去除数组中重复的元素值
Oct 29 PHP
PHP测试程序运行时间的类
Feb 05 PHP
php二维数组排序方法(array_multisort usort)
Dec 25 PHP
php_screw安装使用教程(另一个PHP代码加密实现)
May 29 PHP
Thinkphp搜索时首页分页和搜索页保持条件分页的方法
Dec 05 PHP
php一个解析字符串排列数组的方法
May 12 PHP
PHP实现在线阅读PDF文件的方法
Jun 23 PHP
PHP中静态变量的使用方法实例分析
Dec 01 PHP
PHP实现的mysql主从数据库状态检测功能示例
Jul 20 PHP
PHP 伪静态技术原理以及突破原理实现介绍
Jul 12 #PHP
php的$_FILES的临时储存文件与回收机制实测过程
Jul 12 #PHP
php图像处理函数大全(推荐收藏)
Jul 11 #PHP
PHP 获取远程文件大小的3种解决方法
Jul 11 #PHP
深入Nginx + PHP 缓存详解
Jul 11 #PHP
基于PHP中的常用函数回顾
Jul 11 #PHP
PHP 获取文件权限函数介绍
Jul 11 #PHP
You might like
php上传文件,创建递归目录的实例代码
2013/10/18 PHP
PHP imagegrabscreen和imagegrabwindow(截取网站缩略图)的实例代码
2013/11/07 PHP
PHP中使用socket方式GET、POST数据实例
2015/04/02 PHP
CI映射(加载)数据到view层的方法
2016/03/28 PHP
PHP使用gearman进行异步的邮件或短信发送操作详解
2020/02/27 PHP
为Yahoo! UI Extensions Grid增加内置的可编辑器
2007/03/10 Javascript
jquery中获得$.ajax()事件返回的值并添加事件的方法
2010/04/15 Javascript
利用JS来控制键盘的上下左右键(示例代码)
2013/12/14 Javascript
jQuery中removeProp()方法用法实例
2015/01/05 Javascript
javascript限制文本框输入值类型的方法
2015/05/07 Javascript
javascript删除数组重复元素的方法汇总
2015/06/24 Javascript
喜大普奔!jQuery发布 3.0 最终版
2016/06/12 Javascript
vue实现ajax滚动下拉加载,同时具有loading效果(推荐)
2017/01/11 Javascript
jQuery窗口拖动功能的实现代码
2017/02/04 Javascript
解决html input验证只能输入数字,不能输入其他的问题
2017/07/21 Javascript
JavaScript中的连续赋值问题实例分析
2019/07/12 Javascript
15个简单的JS编码标准让你的代码更整洁(小结)
2020/07/16 Javascript
vue打包静态资源后显示空白及static文件路径报错的解决
2020/09/02 Javascript
使用js和canvas实现时钟效果
2020/09/08 Javascript
[01:45]DOTA2众星出演!DSPL刀塔次级职业联赛宣传片
2014/11/21 DOTA
Python的字典和列表的使用中一些需要注意的地方
2015/04/24 Python
python 从文件夹抽取图片另存的方法
2018/12/04 Python
python3的print()函数的用法图文讲解
2019/07/16 Python
python3.7 的新特性详解
2019/07/25 Python
python 判断txt每行内容中是否包含子串并重新写入保存的实例
2020/03/12 Python
使用PyWeChatSpy自动回复微信拍一拍功能的实现代码
2020/07/02 Python
jupyter notebook更换皮肤主题的实现
2021/01/07 Python
Ubuntu20下的Django安装的方法步骤
2021/01/24 Python
如何通过 CSS 写出火焰效果
2021/03/24 HTML / CSS
外国语学院毕业生自荐信
2013/10/28 职场文书
培训专员岗位职责
2014/02/26 职场文书
爽歪歪广告词
2014/03/20 职场文书
旅游文化节策划方案
2014/06/06 职场文书
学雷锋主题班会教案
2015/08/13 职场文书
2016元旦文艺汇演主持词(开场白+结束语)
2015/12/03 职场文书
MYSQL 表的全面总结
2021/11/11 MySQL