redis+crontab+php异步处理任务
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程序:
while (TRUE) {
$element = $redis->brPop($key, 10); // 阻塞执行, 超时为10s
$content = json_decode($element[1], TRUE);// 返回为PHP数组, 其中$element[0]是队列的名字, $element[1]是内容 (因为brpop可以同时监控多个队列)
}
注意:
1. while true, 看似是死循环, 但是里边的brpop是阻塞型的代码, 队列里边没有数据的时候会让出CPU直到数据的到来, 等待10秒钟后还没有数据就停掉, 进入下一次循环(下一个10s)
2. 因为是死循环, 要一直执行下去, 所以最好的方式是php_cli模式下执行, 这个模式下是不会有超时限制的
3. "read error on connection" 报错, 因为brpop阻塞10s, 所以PHP在连接redis时设置的timeout时间必须得大于这个时间, 或者干脆就不设置超时:
$this->connect('REDIS_HOST', 'REDIS_PORT', 'GLOBAL_TIME_OUT');
$this->auth('REDIS_AUTH');
crontab怎么配合: 定期检查这个PHP脚本是否是在执行, 如果没有就启动它
* * * * * /bin/sh /path/to/watch/bash_script/start.sh online
start.sh:
#!/bin/bash
# 使用了 Redis 的 bRpop 函数去实时监控, 发送报警邮件和短信
# 先检查是否启动了该进程, 没有的话就启动
# 保证该文件是可执行的
# crontab: /bin/sh /path/to/shell.sh env #env: online/test/someone count=`ps -ef | grep process_name | grep -v "grep" | wc -l`
start_time=`date +%Y-%m-%d_%X`
if [ $count -eq ] && [ online = "$1" ] #生产环境
then
echo ${start_time}" start redisLog "
#code here: cd /path/to/onlien/webroot && /path/to/php/bin/php /path/to/shell/file/cli.php args >> /path/to/error.log >& elif [ $count -eq ] && [ test = "$1" ] #公共测试环境
then
echo ${start_time}" start redisLog "
#code here: cd /path/to/test/webroot && /path/to/php/bin/php /path/to/shell/file/cli.php args >> /path/to/error.log >& elif [ $count -eq ] #个人测试环境
then
echo ${start_time}" start redisLog "
#code here: cd /path/to/someone/webroot && /path/to/php/bin/php /path/to/shell/file/cli.php args >> /path/to/error.log >& else
echo ${start_time}" redisLog already running "
fi
这中实现方式可以达到实时的
但是没数据的时候, 死循环会一直阻塞下去, 但貌似也不耗费什么资源
注意 windows 和 Linux的换行符是不一样的, windows转Linux:
vi xxx.sh
:set fileformat=unix
:x
redis+crontab+php异步处理任务的更多相关文章
- Win10系统下使用Django2.0.4+Celery4.4.2+Redis来实现异步任务队列以及定时(周期)任务(2020年最新攻略)
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_153 首先明确一点,celery4.1+的官方文档已经详细说明,该版本之后不需要引入依赖 django-celery 这个库了,直 ...
- StackExchange.Redis 使用-同步 异步 即发即弃 (三)
访问单个服务器 有时候需要为单个服务器指定特定的命令 . IServer server = redis.GetServer("localhost", 6379); GetServe ...
- Redis+Kafka异步提高并发
Redis+Kafka异步提高并发 Redis+Kafka异步提高并发 设计 实现 提交请求接口 Kafka消费队列 异步处理Service 客户端轮询获取结果 Redis集群节点配置 KafKa集群 ...
- redis持久化策略梳理及主从环境下的策略调整记录
redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到磁盘来保证持久化.可以不定期的通过异步方式保存到磁盘上(即“半持久化模式”):也可以把每一次数据变化都写入到一个A ...
- redis参考文档
本文为之前整理的关于redis的文档,放到博客上一份,也方便我以后查阅. redis简介 Redis是一个开源的.高性能的.基于键值对的缓存与存储系统, 通过提供多种键值数据类型来适应不同场景下的缓存 ...
- 缓存技术Redis在C#中的使用及Redis的封装
Redis是一款开源的.高性能的键-值存储(key-value store).它常被称作是一款数据结构服务器(data structure server).Redis的键值可以包括字符串(string ...
- 用StackExchange.Redis客户端连接阿里云Redis服务遇到的问题
阿里云推荐的Redis服务.NET客户端是ServiceStack.Redis,但ServiceStack.Redis不支持异步,不支持.NET Core,于是尝试使用StackExchange.Re ...
- 一个使用高并发高线程数 Server 使用异步数据库客户端造成的超时问题
现象 今天在做一个项目时, 将 tomcat 的 maxThreads 加大, 加到了 1024, tomcat 提供的服务主要是做一些运算, 然后插入 redis, 查询 redis, 最后将任务返 ...
- Redis一些基本的操作
代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Syst ...
随机推荐
- Security Test Cases
https://www.owasp.org/index.php/OWASP_Testing_Guide_v4_Table_of_Contents Username Enumeration Vulner ...
- 页面多次调用查询文章(have_posts())
通常来说一个页面只调用查询一次文章.have_posts() 如果页面,比如首页需要按照不同的查询参数调用多次文章 需要做如下处理: //loop前 $temp_query = $wp_que ...
- [asp.net core]project.json(1)
摘要 前面介绍了使用vs2015新建asp.net core web的内容,这篇文章学习下project.json文件的内容. project.json 原文:https://docs.microso ...
- CSS浮动属性Float介绍
#cnblogs_post_body h6 {font-size: 16px;font-weight: bold;} 什么是CSS Float? float 是 css 的定位属性.在传统的印刷布局中 ...
- 第二章平稳时间序列模型——AR(p),MA(q),ARMA(p,q)模型及其平稳性
1白噪声过程: 零均值,同方差,无自相关(协方差为0) 以后我们遇到的efshow如果不特殊说明,就是白噪声过程. 对于正态分布而言,不相关即可推出独立,所以如果该白噪声如果服从正态分布,则其还将 ...
- 清北暑假模拟day1 艳阳天
/* 注意P有可能不是质数,不要用欧拉函数那一套,正解可以倍增,就是等比数列和的性质,注意n是否为奇数 */ #include <cstdio> #include <algorith ...
- VS上利用C#实现一个简单的串口程序记录
一.背景 工作上需要利用串口往下位机写入数据,VC太老,正好借此机会来熟悉一直很想接触的VS之C#. 感谢Tony托尼哥的串口通信代码,感谢梦真的C#的技术支持. 二.正文 1.项目架构:(以我现有的 ...
- 通过Android录音进行简单音频分析
Android录音有MediaRecorder和AudioRecord两种方式,前者使用方便,可以直接生成录音文件,但是录音格式为aac和amr等等,都经过压缩处理,不方便进行音频分析. 而用Audi ...
- ThinkPHP框架表单验证
对注册到test表的表单进行验证 在注册之前要对表单进行验证: 用户名非空验证,两次输入密码必须一致即相等验证,年龄在18~50之间即范围验证,邮箱格式正则验证. 自动验证是ThinkPHP模型层提供 ...
- javascript高级程序设计---Event对象二
鼠标事件 事件种类 鼠标事件指与鼠标相关的事件,主要有以下一些. (1)click事件 click事件当用户在Element节点.document节点.window对象上,单击鼠标(或者按下回车键)时 ...