• 服务器cli模式下的定时器


    有时候需要一部分后台业务异步的处理,比如处理redis队列啊,处理mysql统计啊,数据同步啊,这种长时间任务,但是又需要每段时间去看看的,发现linux cron最小只能支持每分钟的任务

    分 时 天 月 星期

    这颗粒度太大了,而我们实际业务往往需要几秒一次的查询或者每秒一次的业务,甚至有时候是毫秒级别的任务。

    于是干脆写个后台一直运行的程序一直监控着。

    最简单的方法使用 php while 死循环

    <?php
    while (1) {
    }

    发现这样CPU马上跑满了,这样消耗CPU太厉害也不行,然后给它休息一下也行

    <?php
    while (1) {
        usleep(1000);
    }

    每次1毫秒一次 这样其实CPU也消耗的不太高 百分之2-3左右吧

    如果每1秒一次的话,几乎消耗的就不多了,百分之0.几

    <?php
    while (1) {
        sleep(1);
    }

    对于php开发者而言这也不错。

    然后想想要不试试lua 发现lua 也有很多不同的方案。

    首先可以尝试 while 死循环

    while(1)
    do
        
    end

    CPU都百分之130了,太可怕

    然后加个休息 每秒休息一次

    while(1)
    do
        os.execute("sleep " .. 1)
    end

    发现这样就压根不占用CPU啊!不过然后发现这个时间是秒级别,换个毫秒级别的

    local socket_now = require('socket')
    while(1)
    do
        socket_now.select(nil, nil, 0.001)
    end

    这个就是1毫秒一次了 占用CPU 百分之3-4 也还不错。

    当然完全也可以用swoole的那种定时器,不过感觉那还得搞swoole,得有学习成本,对很多公司的fpm模式而言,有时候只有几个业务是后台常驻需要弄个定时器的,这样也就足够了,简单好维护。

    这里面的业务代码,可以使用redis或者文件缓存等方式,看看是不是有任务,简单迅速的查询是不是需要处理,需要就处理,给开始处理业务上一个锁,避免长时间没执行完,后面的循环又压上来了造成业务执行第二次,有锁了就不做处理等待sleep。

    当然也有可能锁出现问题,一直锁住 导致业务一直无法继续,那就给它加一个过期时间,当锁自然过期后,最终还是能执行进来的,毕竟这程序在一直循环。

    <?php
    while(1)
    {
        $check_flag = check_if_we_have_task_in_redis_or_cache();
        if ($check_flag)
        {
            add_a_lock_for_flag();
            handle_task();
        }
        usleep(1000);
    }
  • 相关阅读:
    MongoDB学习笔记(查询)
    PHP IP地址转换
    PHP SESSION的工作原理解析(转)
    JavaScript 之 RegExp 对象
    jquery 几个实用的小方法
    JS之document.cookie随笔
    CodeForces
    CodeForces
    翻转 -- CodeForces
    Codeforces --- 982C Cut 'em all! DFS加贪心
  • 原文地址:https://www.cnblogs.com/lizhaoyao/p/14906896.html
Copyright © 2020-2023  润新知