redis+crontab+php异步处理任务

本文涉及的产品
云数据库 Redis 版,标准版 2GB
推荐场景:
搭建游戏排行榜
云原生内存数据库 Tair,内存型 2GB
简介: 2016年1月8日 16:08:43 星期五 情景: 用户登录日志, 发邮件, 发短信等等实时性要求不怎么高的业务通常会异步执行 之前接触过几种redis+crontab配套的实现方法, 比如: crontab定时执行curl脚本   1.

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 }

注意:

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

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

3. "read error on connection" 报错, 因为brpop阻塞10s, 所以PHP在连接redis时设置的timeout时间必须得大于这个时间, 或者干脆就不设置超时:

1 $this->connect('REDIS_HOST', 'REDIS_PORT', 'GLOBAL_TIME_OUT');
2 $this->auth('REDIS_AUTH');

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

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

start.sh:

 1 #!/bin/bash
 2 # 使用了 Redis 的 bRpop 函数去实时监控, 发送报警邮件和短信
 3 # 先检查是否启动了该进程, 没有的话就启动
 4 # 保证该文件是可执行的
 5 # crontab:  /bin/sh /path/to/shell.sh env #env: online/test/someone
 6 
 7 count=`ps -ef | grep process_name | grep -v "grep" | wc -l`
 8 start_time=`date +%Y-%m-%d_%X`
 9 if [ $count -eq 0 ] && [ online = "$1" ] #生产环境
10 then
11     echo ${start_time}" start redisLog "
12     #code here: cd /path/to/onlien/webroot && /path/to/php/bin/php /path/to/shell/file/cli.php args >> /path/to/error.log 2>&1
13 
14 elif [ $count -eq 0 ] && [ test = "$1" ] #公共测试环境
15 then
16     echo ${start_time}" start redisLog "
17     #code here: cd /path/to/test/webroot && /path/to/php/bin/php /path/to/shell/file/cli.php args >> /path/to/error.log 2>&1
18 
19 elif [ $count -eq 0 ] #个人测试环境
20 then
21     echo ${start_time}" start redisLog "
22     #code here: cd /path/to/someone/webroot && /path/to/php/bin/php /path/to/shell/file/cli.php args >> /path/to/error.log 2>&1
23 
24 else
25     echo ${start_time}" redisLog already running "
26 fi

 

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

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

 

 summerPHP

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
13天前
|
缓存 NoSQL 网络安全
【Azure Redis 缓存】Azure Redis服务开启了SSL(6380端口), PHP如何访问缓存呢?
【Azure Redis 缓存】Azure Redis服务开启了SSL(6380端口), PHP如何访问缓存呢?
|
4月前
|
存储 监控 负载均衡
保证Redis的高可用性是一个涉及多个层面的任务,主要包括数据持久化、复制与故障转移、集群化部署等方面
【5月更文挑战第15天】保证Redis高可用性涉及数据持久化、复制与故障转移、集群化及优化策略。RDB和AOF是数据持久化方法,哨兵模式确保故障自动恢复。Redis Cluster实现分布式部署,提高负载均衡和容错性。其他措施包括身份认证、多线程、数据压缩和监控报警,以增强安全性和稳定性。通过综合配置与监控,可确保Redis服务的高效、可靠运行。
219 2
|
7天前
|
数据库连接 PHP 数据库
PHP中创建自定义函数以简化日常任务
【8月更文挑战第31天】在PHP编程中,自定义函数是提升代码重用性和清晰度的关键。本文将引导你了解如何创建和使用自定义函数,以及它们如何帮助你的日常开发工作变得更加高效。我们将通过具体案例探讨函数的构建,参数传递,返回值处理,并展示如何通过自定义函数简化复杂任务和减少冗余代码。
|
3月前
|
NoSQL 关系型数据库 MySQL
linux服务器重启php,nginx,redis,mysql命令
linux服务器重启php,nginx,redis,mysql命令
54 1
|
4月前
|
缓存 NoSQL PHP
【PHP 开发专栏】Redis 作为 PHP 缓存的解决方案
【4月更文挑战第30天】本文探讨了Redis作为PHP缓存的优势,如高性能、丰富数据结构、数据持久化和分布式支持。通过安装配置Redis、选择PHP客户端、执行读写操作及制定缓存策略实现缓存。应用场景包括页面、数据和会话缓存。但需注意数据一致性、过期时间、容量和安全问题,以确保应用稳定和安全。Redis能有效提升PHP应用响应速度和处理能力。
114 2
|
4月前
|
缓存 NoSQL Java
面试官:Redis如何实现延迟任务?
延迟任务是计划任务,用于在未来特定时间执行。常见应用场景包括定时通知、异步处理、缓存管理、计划任务、订单处理、重试机制、提醒和数据采集。Redis虽无内置延迟任务功能,但可通过过期键通知、ZSet或Redisson实现。然而,这种方法精度有限,稳定性较差,适合轻量级需求。Redisson的RDelayedQueue提供更简单的延迟队列实现。
411 9
|
4月前
|
存储 缓存 NoSQL
Redis实现延迟任务的几种方案
Redis实现延迟任务的几种方案
|
4月前
|
存储 NoSQL Java
Redis 实现延迟任务的深度解析
【4月更文挑战第17天】
205 0
|
4月前
|
监控 NoSQL 测试技术
python使用Flask,Redis和Celery的异步任务
python使用Flask,Redis和Celery的异步任务
|
4月前
|
NoSQL Linux PHP
php添加redis扩展 linux和windos图文详解 l
php添加redis扩展 linux和windos图文详解 l
32 0
下一篇
DDNS