首页 > 其他 > 详细

redis+crontab异步处理任务

时间:2016-01-08 18:34:42      阅读:199      评论:0      收藏:0      [点我收藏+]

2016年1月8日 16:08:43 星期五

情景: 用户登录日志, 发邮件, 发短信等等实时性要求不怎么高的业务通常会异步执行

之前接触过几种redis+crontab配套的实现方法,

比如: crontab定时执行curl脚本

  1. 用curl 访问URL执行PHP脚本去pop队列

  2. PHP程序pop一次并处理后返回同样的URL

  3. curl收到这个URL后就可以再次跟踪访问并执行该PHP程序, 这样就可以实现循环pop的效果

  4. 最后给curl设定下最大跟踪次数(--max-redirs), 就可以限定每次pop的最大值

  但总感觉那么不顺畅

  1. 不是实时的

  2. 不同时间段打入队列的数据是不确定的, 比如白天登录用户会比晚上多, crontab执行频率不好的话, 白天入队列的数据可能大于出队列的数据导致延时加大

这两天学到了一个新的方法, 可以解决实时性的问题:

PHP程序: 一个阻塞型的死循环去pop队列

crontab:去监控这个PHP循环是不是在运行, 没有则启动

PHP程序:

1 while (TRUE) {
2     $element = $redis->brPop($key, 10); // 阻塞执行, 超时为10s钟
3     $content = json_decode($element[1], TRUE);// 返回为PHP数组, 其中$element[0]是队列的名字, $element[1]是内容 (因为brpop可以同时监控多个队列)
4 }

while true, 看似是死循环, 但是里边的brpop是阻塞型的代码, 队列里边没有数据的时候会让出CPU直到数据的到来, 等待10秒钟后还没有数据就停掉, 进入下一次循环(下一个10s)

因为是死循环, 要一直执行下去, 所以最好的方式是php_cli模式下执行, 这个模式下是不会有超时限制的

crontab是怎么配合: 定期检查这个PHP脚本是否是在执行, 如果没有就启动它

* * * * * /path/to/watch/bash_script/start.sh

start.sh:

 1 #!/bin/bash
 2 # remember chmod +x
 3 
 4 #判断进程是否存在
 5 count=`ps -ef | grep php/cli/script/name | grep -v "grep" | wc -l`
 6 
 7 #如果不存在就启动, 并把输出信息或错误信息写到日志里边
 8 if [ $count -eq 0 ]; then
 9     cd /path/to/web/root && /path/to/bin/php /path/to/cli_test.php params > /tmp/brpop.log 2>&1
10 fi

这中实现方式可以达到实时的

但是没数据的时候, 死循环会一直阻塞下去, 单貌似也不耗费什么资源

redis+crontab异步处理任务

原文:http://www.cnblogs.com/iLoveMyD/p/5113865.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!