PHP定时器 生态

常见的定时器有两种:一种周期性定时执行,例如每天的凌晨三点出报表;另一种在指定时间后执行(一次),例如会员登录系统五分钟后发放每日登录奖励。两种情况对应shell中的cron和at命令,与JavaScript中的setInterval和setTimeout函数类似(严格来说setInterval是周期性执行,指定时间点执行需要自行处理)。

做web开发的PHP程序员对JavaScript中的两个定时器函数应该都还挺熟悉,回到PHP层面就有点傻眼:PHP中有sleep,但是没有(内置)定时器函数可用。sleep函数勉强可以做到,但会导致进程阻塞,期间不能做其他事(或无响应)。为什么PHP没能提供定时器(Timer)这个功能呢?

正确的姿势 PHP实现定时器功能的做法可简单归结为如下几种:

使用cron、Jenkins等调度工具做周期性定时任务(既可以是执行脚本,也可以是请求某个网址); 一次性执行任务通过消息队列、数据库等方式投递给第三方程序执行; 像WordPress一样模拟定时任务,但要记住这种方式依赖于客户端请求,并需自行处理好进程并发问题; 使用常驻内存型方式运行PHP程序,即CLI模式。 除了第三种做法,其他方式都是推荐的,具体方案请结合实际需求。作为PHP程序员,当然还是首选用PHP来做,也就是CLI模式。

CLI模式 摸着良心说,CLI模式让PHP发挥的空间拓展不少。在CLI模式下,程序的入口点就是脚本,且代码可以常驻内存,进程完全由PHP代码控制。在这种形式下,实现定时器就有多种玩法。本文列出几种做法,抛砖引玉:

使用swoole、workerman等框架,内置(高精度)定时器; 使用多进程(池)/多线程(池)技术(pcntl、pthreads拓展在CLI模式下才可用); 处理tick或者alarm等信号; 使用libevent、libev等事件驱动库; sleep加循环或自己实现事件循环。 想折腾的话自己用2-5方案,不想折腾swoole、workerman等框架是首选,稳定可靠。

记录你我
请先登录后发表评论
  • latest comments
  • 总共0条评论