第七星尘的独立博客

PHP实现轮询速度智能变速

做开发的时候我们可能需要不断轮询抓取网络数据。比如说如果要监控一个用户的微博feed更新,我们一般的解决方案是定时(如1分钟1次)查询服务器看看有没有新数据。但,请设想这么一种情形:

1,需要监控的用户越来越多。完整地轮询完所有用户需要耗费的时间越来越长
2,业务上要求,用户的微博更新时,尽可能地及时监控到。而所耗费的时间越长,会让监控严重滞后。
3,实际发现,绝大部分的用户的微博是很少更新甚至一个月都不更新的。而少部分的用户则非常活跃,每天几十条甚至上百条。
在这种情形下,如果我们还按照原方案,每个用户都轮询一遍来检查有没有新微博的话,那样会导致轮询一遍的时间太长。活跃用户发了一条微博,可能一个小时后才会被监控到。这样太滞后了。我们需要设计一套更加有效的方案才行。
这套方案的原则是:优先监控活跃用户,减少对寂静用户的监控时间。
用文字来描述这个过程就是:定时检查用户的微博更新状态;对于没有更新的,将逐渐减小轮询的频率。当发现有了微博更新,将重置轮询频率为原来的数值。这个过程也可以称为轮询速度智能变速。
为了实现这个过程,我写了一个PHP类。这个类并不是通用的类,它本来是专门为我的程序写的,所以它也许不适用在你的程序上,但希望它能为有类似需求的人提供一种解决思路。
/**
*  变速器
*/
class Transmission
{
    private $mc ;
    private $account ;
    function __construct()
    {
        $this->mc = $GLOBALS['mmc'] ? $GLOBALS['mmc'] : memcache_init();
    }
    function set_account($account){
        $this->account = $account ;
    }
    //判断是否应该执行(根据时间判断)
    function is_execute(){
        $is_execute = 0 ;
        $next_execute_time = $this->get_next_time($this->account);
        if ($next_execute_time) {
           if ($next_execute_time < time() ) {
               $is_execute = 1 ;
           }
        }else{
            $is_execute = 1 ;
        }
        return $is_execute ;
    }
    //设置下次可执行的时间
    function set_next_time(){
        $times = $this->get_times($this->account);
        $times = $times > 30 ? 30 : $times+1 ;
        memcache_set($this->mc,'no_change_times_'.$this->account, $times , 0, 29*24*60*60 );
        $next_execute_time = time() + ($times+1)*60;//当前时间+(次数+1)*分钟
        memcache_set($this->mc,'next_execute_time_'.$this->account, $next_execute_time , 0, 29*24*60*60 );
    }
    //重置,恢复默认访问时间
    function reset(){
        //默认0次
        memcache_set($this->mc,'no_change_times_'.$this->account, 0 , 0, 29*24*60*60 );
        $next_execute_time = time() + 60;//当前时间+1分钟
        memcache_set($this->mc,'next_execute_time_'.$this->account, $next_execute_time , 0, 29*24*60*60 );
    }
    //获取次数
    function get_times(){
        $times = memcache_get($this->mc,'no_change_times_'.$this->account);
        return $times;
    }
    //获取下次执行时间
    function get_next_time(){
        $next_execute_time = memcache_get($this->mc,'next_execute_time_'.$this->account);
        return $next_execute_time;
    }
}
 如无特殊说明,本站皆为原创。转载请注明来自第七星尘的独立博客《PHP实现轮询速度智能变速》

评论

  1. 付学军 #1

    厉害厉害

    回复
    2018-11-20
  2. hua #2

    话说fabuduan你还有在维护吗?

    回复
    2016-04-5
  3. 陈正义 #3

    你作品里的MP3音乐盘不错,不知能提供源码吗?

    回复
    2015-05-4