消息队列
浏览数 100820
最后修改时间
有些事务我们需要做成异步处理,这样可以得到更好的用户体验,也可以把耗时又耗性能的事情转移到专用的服务器去处理,比如图片处理、发送邮件、发送短信、统计数据等等,这时我们就能用到消息队列,例如服务器收到用户发送邮件的请求,可以把发邮件的事项以消息的方式发送给消息队列,不用等待发送完成即可立即返回提示给用户,消息队列收到消息后即处理发送邮件的事务,这是用户感知不到的。这样,用户触发发邮件的事件后很快得到了“邮件已经发送”的反馈,避免了焦虑等待,同时,我们的WEB服务器只接收请求,避免了耗时拥堵,处理消息队列的事情交给另一台服务器去做,分散了性能上的压力,并且可以分配多台服务器去处理消息列表。
例如停止刚刚的发邮件队列可以这样
action的可选方法有:不建议强制从后台杀掉消息队列的进程,因为很容易中断执行到一半的程序,导致数据问题。
YiluPHP 的消息队列使用高速的 Redis 缓存实现,消息队列的流程可分为:发送消息、存储消息、监听消息、处理消息、处理失败时重试。
使用YiluPHP的消息队列的开发流程如下:
一、使用 add_to_queue 函数发送消息
add_to_queue($class_name, $data, $queue_name='default', $delay_second=0, $to_first=false);
参数说明
$class_name:字符串,处理队列的类名,即 /cli/queue/ 目录中对应的类名。
$data:消息的内容,支持的数据类型有 string/array/numeric/boolean ,读取消息时将原样返回。
$queue_name:字符串,队列的名称,默认的队列名称叫default,你可以定义自己的队列名称,例如按事务的类型取email、sms,或者按使用的频率取 low_frequency、common_frequency、high_frequency,同一个名称的队列内消息是从前往后的顺序一一处理的,因此合理得把消息分配到不同的队列中,可以得到更好的性能。
$delay_second:整数,单位为秒,有些消息你希望延迟处理,这个参数就起到了作用,你可以设置你希望延迟的秒数。
$to_first:boolean,是否优先处理,true为放到第一个处理,false则会按正常的队列顺序执行。
二、开发处理消息的类
处理消息类的名称要与发送消息时 add_to_queue() 第一个参数的名称一致,处理消息的类存放在 /cli/queue/ 目录中,框架自带一个发邮件的示例 /cli/queue/send_email_code.php,这个示例是运行不起来的,因为缺少发送邮件的工具类 tool_mailer,它的用处是:你可以参照这个示例写出你的处理消息类。
处理消息的类必需要实现 run 方法,run 方法有一个参数 $msg ,这个参数的值就是发送消息时 add_to_queue 函数的第二个参数的值,被原样传递过来了。如果消息处理成功,run方法必须返回 boolean 值 true,这样这个消息就会在消息队列中被删除,不返回或返回false都表示处理失败,下次会再次处理这个消息,重试处理失败消息的频率是:前10次每6秒一次,10次以后每1分钟一次,直到处理成功(即run方法返回true)为止。
三、设置监听消息队列
消息列队有两种模式,同步运行模式和异步运行模式,可以通过配置信息 $config['queue_mode'] 的值来设置,queue_mode的值是sync为同步运行,是asyn为异步运行,如果不设置,默认为异步运行。
同步运行模式下不用设置消息队列的监听,因为 add_to_queue() 函数在添加消息就会同步运行消息的处理代码,在等待执行完消息的处理码执行完成后才会返回,这种模式适合于开发和调度。
在异步运行模式下,需要设置消息队列的监听,只有监听到消息才会读取消息和处理消息。监听消息的方式就是让一个PHP文件在后台一直运行着,轮询监听Redis中是否有新的消息。进入 Linux 服务器的今天控制台,在 CLI(命令行界面英语:command-line interface,缩写:CLI)下运行
[php安装路径]php [项目目录]queue "queue_name=[队列名称]" &
例如有队列/cli/queue/send_email_code.php,我的php安装在/usr/local/php-7.1.1/,项目文件放在/data/web/www.yiluphp.com/,我在添加消息时(add_to_queue() 函数的第三个参数)指定队列名称为 email_queue ,则执行命令
/usr/local/php-7.1.1/bin/php /data/web/www.yiluphp.com/queue "queue_name=email_queue" &
后面加空格和&是让它一直在后台运行着,即使我把命令窗口关闭了,它还会在后台运行着。但某些情况下它会中止退出,例如程序出错,或者代码中有写退出的逻辑(这是不建议的),为了使它能在后台一直运行着,你最好使用一个进程守护软件,如:Supervisor,进程守护软件可以在你的进程停止后自动重启,确保消息队列的监听一直在后台运行着。你可以网上搜索“Supervisor的安装和配置” 得到相关信息。
如果你的项目里使用了多个消息队列的名称,则每一个队列的名称都需要设置对应的监听,如果某个名称的消息特别多,可以启动多个监听在后台处理,也可以在多台服务器启动相同队列名称的监听。
消息队列的相关操作
上面我们学习了消息队列的监听,也就是消息队列的启动,那么怎么停止、暂停、重启和删除队列呢?只需要在启动消息队列的命令的基本上增加一个action的参数即可,并且不需要最后面的&符号了。由于多个参数使用&连接,所以一定要用双引号把参数包含起来,否则参数中的&会被当作是命令符执行。
[php安装路径]php [项目目录]queue "queue_name=[队列名称]&action=[操作方法]"
例如停止刚刚的发邮件队列可以这样
/usr/local/php-7.1.1/bin/php /data/web/www.yiluphp.com/queue "queue_name=email_queue&action=stop"
action的可选方法有:
- stop:停止当前队列,正在执行的消息将继续执行完毕,仍然接收新的消息加入队列,但不会有消息再执行。
- pause:暂停当前队列,正在执行的消息将继续执行完毕,仍然接收新的消息加入队列,但不会有消息再执行。
- start:启动已经停止或暂停的队列