[PhalApi实战篇(1)]Redis队列处理异步任务

[PhalApi实战篇(1)]Redis队列处理异步任务

前言

先在这里感谢phalapi框架创始人@dogstar,为我们提供了这样一个优秀的开源框架.

哈喽大家好呀!之前编写的PhalApi入门篇和进阶篇已经过去了好久了,在此之间也回答了很多小伙伴各种各样的问题,这里也希望吧里面一些问的比较多的和比较有趣的以及笔者在使用PhalApi一些新的体会,都提取出来为大家带来一些能够在实际开发中可以使用的技术或思想,那么我们就开始我们实战篇中的第一节 Redis队列处理异步任务

大家希望喵咪在PhalApi实战推出一些什么样的内容?可以私信我邮箱wenzhenxi@vip.qq.com

附上:

喵了个咪的博客:w-blog.cn

官网地址:http://www.phalapi.net/

开源中国Git地址:http://git.oschina.net/dogstar/PhalApi/tree/release

1.为什么需要队列

为什么需要队列?其实已经是一个老生常谈的一个问题了,队列有诸多好处比如:

在项目中,将一些无需即时返回且耗时的操作提取出来,进行了异步队列处理,而这种异步队列处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量。 比较通俗易懂的解释就是 一个请求处理一些事情 A 业务耗时 30ms B业务 耗时 20ms 然后发邮件 耗时 50ms ,吧其中的发送邮件 写入队列 有一个专门负责发送邮件的程序接受这个队列的消息在吧邮件发送出去,这样这个请求原来要用100ms现在只需要50ms , 借助队列可以吧很多原本很消耗时间的操作单独有序处理

队列软件也很多:RabbitMQ,KafKa这两款都是非常主流的队列软件PhalApi也有提供对应的扩展程序来去使用,但是需要使用它们的成本对相对高一些需要搭建很多复杂的组件,但是相对redis,redis虽然没有那么多丰富的功能工具但是它也是队列软件中的不二之选

2.理解Redis处理队列特点

对于PHP来说对Redis支持是特别好的,redis的单线程保障了队列不会应为并发的问题导致一条消息多人获取所有也是很适合做为队列传输,PhalApi不仅仅自带简单的Redis库笔者也在它的基础上封装了一个更为完善的redis库,如下:

Redis · 暗夜在火星/PhalApi Library - 码云 - 开源中国

队列主要由两部分组成一部分是客户端一部分是消费端,客户端负责提供消息消费端负责处理队列这样的一个形式

在使用redis队列主要会使用到redis队列中的List类型,List类型可以从左右两边读取和写入数据,这样的形式就可以做到先入先出或者是后入先出这种队列模式

3.具体实践(基于PhalApi-Redis扩展)

客户端的使用比较简单只需要初始化Redis链接后向左边写入数据即可:

客户端:

//redis链接
DI()->redis = new Redis_Lite(DI()->config->get('app.redis.servers'));
//写入队列左边
DI()->redis->set_lPush(队列键名,值, 库名);

关键是消费端的用法,怎么让消费端一直不停的处理队列呢?很多童鞋应该已经想到了利用死循环不停的读取队列处理来解决及时处理的问题,但是这样又会带来一个新的问题,如果说队列空了死循环会不会一直高额的消耗CPU资源啊?由于这点就衍生出来两种具体的用法:

用法一

有的小伙伴就说了,这个还不简单吗?当队列里面没有内容了我就关掉消费端,然后使用crontab过一段时间再启动进行处理,这就没有所谓的死循环CPU消耗的问题了,这种解法如下:

while (true) {
    // 读取队列右边
    $msg = DI()->redis->get_rPop(队列键名, 库名);
  if( !$msg ){
      break;
  }
    // 处理逻辑
  .....
}

然后通过crontab进行定时任务即可

用法二

第二种用法是通过redis队列的另外一种机制来解决这类问题,相对于get_rPop还有提供一个方法get_brPop,我们可以看一下这个方法的描述读取队列右边 如果没有读取到阻塞一定时间这个阻塞时间是通过配置文件blocking字段来配置的,使用方式如下

while (true) {
    // 读取队列右边
    $msg = DI()->redis->get_brPop(队列键名, 库名);
    // 处理逻辑
  .....
}

这种方法相对上面那种的好处是实时性最好,如果阻塞时间设置的是5秒等待了2秒有消息进来了就里面会进入处理模式

上述方式可以使用Supervisor进行常驻内存执行

总结

本次实战篇为大家讲述了怎么使用Redis来处理队列来处理异步任务,以及队列有什么特点为什么使用redis队列,那么后续的实战篇也会为大家带来比较使用的PhalApi各项技术,如果大家有什么希望喵咪能够加入到实战篇的内容可以@我哦!

注:笔者能力有限有说的不对的地方希望大家能够指出,也希望多多交流!

官网QQ交流群:①群:421032344 ②群:459352221 欢迎大家的加入!

时间: 2024-09-18 00:58:59

[PhalApi实战篇(1)]Redis队列处理异步任务的相关文章

基于redis的邮件异步发送

基于redis的邮件异步发送 相关工具和内容 安装Redis服务 编写Yii2的插件类 重写SwiftMailer类的方法 提交compsoer 提交至github 提交至composer 测试使用composer下载 安装redis服务 redis官网reids.io 下载地址 当前稳定版本链接http://download.redis.io/releases/redis-4.0.1.tar.gz mkdir redis cd redis wget http://download.redis.

PHP实现电商订单自动确认收货redis队列

一.场景 之前做的电商平台,用户在收到货之后,大部分都不会主动的点击确认收货,导致给商家结款的时候,商家各种投诉,于是就根据需求,要做一个订单在发货之后的x天自动确认收货.所谓的订单自动确认收货,就是在在特定的时间,执行一条update语句,改变订单的状态. 二.思路 最笨重的做法,通过linux后台定时任务,查询符合条件的订单,然后update.最理想情况下,如果每分钟都有需要update的订单,这种方式也还行.奈何平台太小,以及卖家发货时间大部分也是密集的,不会分散在24小时的每分钟.那么,

关于下载GAE High Replication Datastore数据[实战篇]下

通过bulk loader可以批量上传下载数据,GAE支持xml,csv格式数据批量上传,以及xml,csv和文本 格式下载. 你可以选择自动生成一个bulkloader.yaml,或者手动编码来写一个bulk loader.谷歌不推荐手动编 写,个人也觉得自动生成才是王道. 如何自动生成bulkloader.yaml bulkloader.yaml是一个描述数据格式的配置文件,格式例如xml或csv.bulk loader进行数据导入时 需要这个配置文件来将外部数据(xml或csv)转换为中间

【高并发简单解决方案】redis队列缓存 + mysql 批量入库 + php离线整合

需求背景:有个调用统计日志存储和统计需求,要求存储到mysql中:存储数据高峰能达到日均千万,瓶颈在于直接入库并发太高,可能会把mysql干垮. 问题分析 思考:应用网站架构的衍化过程中,应用最新的框架和工具技术固然是最优选择:但是,如果能在现有的框架的基础上提出简单可依赖的解决方案,未尝不是一种提升自我的尝试. 解决: 问题一:要求日志最好入库:但是,直接入库mysql确实扛不住,批量入库没有问题,done.[批量入库和直接入库性能差异参考文章] 问题二:批量入库就需要有高并发的消息队列,决定

iOS与JS交互实战篇(Swift/ObjC)

前言 ObjectiveC与Js交互是常见的需求,可对于新手或者所谓的高手而言,其实并不是那么简单明了.这里只介绍iOS7.0后出来的JavaScriptCore framework. 关于JavaScriptCore 本教程中所涉及到的几种类型: JSContext, JSContext是代表JS的执行环境,通过-evaluateScript:方法就可以执行一JS代码 JSValue, JSValue封装了JS与ObjC中的对应的类型,以及调用JS的API等 JSExport, JSExpor

redis队列处理文件并发(日志处理)

    多线程操作同一个文件时会出现并发问题.解决的一个办法就是给文件加锁(lock),但是这样的话,一个线程操作文件时,其它的都得等待,这样的话性能非常差. 另外一个解决方案,就是先将数据放在队列中,然后开启一个线程,负责从队列中取出数据,再写到文件中. using log4net; using RedisMvcApp.Models; using System; using System.Collections.Generic; using System.IO; using System.Li

redis 队列问题 java

问题描述 redis 队列问题 java 项目中,并发使用redis队列缓存信息,然后出队列执行业务代码,但是队列名,一段时间就有问题了,插入队列,监听不到有数据,可能根本就没插进去,换个队列名就正常了,过段时间又会出现同样的问题,哪位大神可以指导下. 没分了,不好意思 解决方案 redis单点故障问题 解决方案二: 是不是对应队列还存在不,用redis-cli等查看一下对应杜列中的数据,是不是被阻塞了 解决方案三: 第一,我觉得可能自动清除了这个队列,第二,还有你存这个队列的时候是怎么存的.

JBuilder9+Weblogic7实战篇之工具篇(JDBC 1)

JBuilder9+Weblogic7实战篇<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> 工具篇(配置JDBC 1)                                                                              作者:黄 凯         E_mail:hk_sz@163.com Weblogic7中配置J

Android多功能时钟开发案例(实战篇)_Android

上一篇为大家介绍的是Android多功能时钟开发基础内容,大家可以回顾一下,Android多功能时钟开发案例(基础篇) 接下来进入实战,快点来学习吧. 一.时钟在布局文件中我们看到,界面上只有一个TextView,这个TextView的作用就是显示一个系统的当前时间,同时这个时间还是一秒一秒跳的,要实现一秒一秒的跳就需要我们每隔一秒就要刷新一下,同时我们这里还考虑了切换到另一个Tab的时候,这个时间就不跳动了,这样就会减少这个对系统的占用,考虑到了这点我们在这里用到了Handler,通过hand