2020 年了,现在最简单的 PHP 执行异步任务的方式是什么,不要框架,尽量十几二十行 PHP 代码能搞定? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
frozenway
V2EX    PHP

2020 年了,现在最简单的 PHP 执行异步任务的方式是什么,不要框架,尽量十几二十行 PHP 代码能搞定?

  •  
  •   frozenway Jun 12, 2020 8070 views
    This topic created in 2144 days ago, the information mentioned may be changed or developed.

    想在这台服务器(国内)php 保存某些数据后,去更新另外一台服务器(国外)的文件缓存,如果是同步更新,保存数据的响应结果会太慢太卡,想着异步去做。要求尽量简单,不想左一个框架右一个框架,不用 redis,memkache 等,因为开启这些扩展需要编译 php,麻烦

    44 replies    2020-06-23 15:31:53 +08:00
    luyaolu
        1
    luyaolu  
       Jun 12, 2020
    接口请求另一个接口 我想到最简单的
    CODEWEA
        2
    CODEWEA  
       Jun 12, 2020
    搜索关键词:linux 进程通信
    yakumo520
        3
    yakumo520  
       Jun 12, 2020
    那你干脆不用 php 吧,直接 linux 协程
    qiayue
        4
    qiayue  
    PRO
       Jun 12, 2020
    每一步一个 php 文件,假设 3 步,那就 3 个文件
    step1.php 执行完之后,跳转到 step2.php ,执行完之后再跳转到 step3.php ,执行完之后跳回 step1.php
    每次 step1.php 来判断是否有新的任务需要执行。
    注意跳转不要用 header location 形式,而是用 html meta refresh 形式,延迟 1 秒跳转

    然后你就开浏览器让他不断自动执行就行。
    frozenway
        5
    frozenway  
    OP
       Jun 12, 2020
    @qiayue 这个方法不错
    richangfan
        6
    richangfan  
       Jun 12, 2020 via Android
    加个定时任务
    TORYOI
        7
    TORYOI  
       Jun 12, 2020
    @qiayue 我以前用过这种方式,只是感觉好别扭
    mokeyjay
        8
    mokeyjay  
       Jun 12, 2020   1
    crontab -e
    php job.php
    keepeye
        9
    keepeye  
       Jun 12, 2020
    单独写个服务,提供一个任务接口,调用接口的时候 fork 子进程处理,直接返回不用等待处理结果
    whahugao
        10
    whahugao  
       Jun 12, 2020
    用 popen 另外起一个 php 进程去执行异步任务呗
    ben1024
        11
    ben1024  
       Jun 12, 2020
    要是数据库可以用 canal
    纯文件挂文件流传输,一个点开,一个点请求
    yuzo555
        12
    yuzo555  
       Jun 12, 2020
    如果只是这个简单的需求,那么 PHP 是可以先响应然后继续执行的呀。

    https://stackoverflow.com/questions/15273570/continue-processing-php-after-sending-http-response
    Ech0o0
        13
    Ech0o0  
       Jun 12, 2020
    ```php
    <?php

    set_time_limit(30);
    ignore_user_abort(false);

    header("Content-Length: 0");
    header("Connection: Close");
    echo str_pad('', ini_get('output_buffering'));
    ob_end_flush();
    ob_flush();
    flush();

    //耗时任务
    sleep(10);
    file_put_contents('test.log', date('Y-m-d H:i:s'), FILE_APPEND);
    ```

    ```php
    <?php

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, 'http://127.0.0.1/async.php');
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_exec($curl);
    curl_close($curl);

    echo '结束了';
    ```

    有局限性,最好还是用队列吧
    explore365
        14
    explore365  
       Jun 12, 2020
    还是用一下框架吧,workerman,比较简单一些
    frozenway
        15
    frozenway  
    OP
       Jun 12, 2020
    @yuzo555 这个长见识了
    luckyrayyy
        16
    luckyrayyy  
       Jun 12, 2020
    crontab 系统自带啊
    I2E
        17
    I2E  
       Jun 12, 2020
    尝试过,没搞出来,应该没法光靠 php 。说 sleep 的是认真的吗?
    I2E
        18
    I2E  
       Jun 12, 2020
    php 只能启多个进程去搞
    I2E
        19
    I2E  
       Jun 12, 2020
    我们现在通过这种方式实现异步任务。通过 pm2 启动一个 rabbitmq 死信队列,设置到期时间。一旦到期就会执行指定任务
    AngryPanda
        20
    AngryPanda  
       Jun 12, 2020
    @I2E fastcgi_finish_request
    caola
        21
    caola  
       Jun 12, 2020
    swoole,编译只是一条命令而已
    GG668v26Fd55CP5W
        22
    GG668v26Fd55CP5W  
       Jun 12, 2020
    beanstalkd 简单粗暴
    Tokin
        23
    Tokin  
       Jun 12, 2020
    记得当时弄的一个简单的队列,后来改用 node 了。
    dadmin
        24
    dadmin  
       Jun 12, 2020
    国外服务器更新缓存功能写成接口 (需要设置 set_time_out(0); ignore_user_abort(true);)
    国内服务器通过 curl 请求国外更新缓存接口 并设置执行超时时间
    kaneg
        26
    kaneg  
       Jun 12, 2020 via iPhone
    crontab 就是干这个活的
    Enivel
        27
    Enivel  
       Jun 13, 2020
    fastcgi_finish_request 正解啊 应该是最简单方式了一行代码搞定.
    edk24
        28
    edk24  
       Jun 13, 2020
    RabbitMQ, 最近刚用上这个队列功能处理视频转码.
    http://aili.edk24.com/1754293

    也许可以试一下, 消费者和生产者连接同一个服务, 生产者投递任务即时响应返回, 消费者在另一个服务器收到任务对它进行处理


    同步文件可以用 scp 之类的命令. 个人不精的建议. 也就 docker 运行个 Rabbitmq, 其他还真是几行代码
    edk24
        29
    edk24  
       Jun 13, 2020
    或者 swoole 有异步任务
    PHPJit
        30
    PHPJit  
       Jun 13, 2020 via iPhone
    fastcgi_finish_request
    raysonlu
        31
    raysonlu  
       Jun 13, 2020
    “开启这些扩展需要编译 php,麻烦” 。。。???
    yincrow
        32
    yincrow  
       Jun 13, 2020
    swoole 的 worker 可以满足
    jay4497
        33
    jay4497  
       Jun 13, 2020
    曾经用 curl 做过类似的,就是发 curl 请求,设置不需要返回结果,然后再设个一秒的超时时间,效果就是程序到这会停一秒,然后就继续执行了,不会等待那边处理完成返回结果。。。
    pandait
        34
    pandait  
       Jun 13, 2020
    用鸟哥的那个 blog 的 fsockopen
    realpg
        35
    realpg  
    PRO
       Jun 13, 2020
    @frozenway #5 PHP 海量数据下 删除数据、生成数据防卡死的标准操作 自刷新也可以
    ViggoSite
        36
    ViggoSite  
       Jun 13, 2020
    系统定时任务 或者 workman,简单又方便
    encro
        37
    encro  
       Jun 13, 2020
    dnf or apt install php-redist 还好吧
    workerman swoole Gearman 也还好吧
    phpize 也麻烦?
    blurh11E27
        38
    blurh11E27  
       Jun 13, 2020
    redis 发布订阅
    go522000
        39
    go522000  
       Jun 13, 2020
    以前用过 fsockopen 做异步请求,挺好用,你可以搜索相关文章参考一下。
    yincrow
        40
    yincrow  
       Jun 13, 2020
    @yincrow 我看了下 swoole 的文档,coroutine 和 process
    sagaxu
        41
    sagaxu  
       Jun 13, 2020 via Android
    “报告长官,有人在诋毁和攻击 PHP”
    “他都胡说八道些什么?”
    “他竟然把 PHP 特性和技巧讲了一遍”
    msg7086
        42
    msg7086  
       Jun 13, 2020
    建议招个运维,解决一下开 PHP 扩展要编译 PHP 的问题。
    cbasil
        43
    cbasil  
       Jun 15, 2020
    最简单的使用 fsockopen
    $fp = fsockopen ( $hostname, $port, $errno, $errstr, 600 );
    stream_set_blocking ( $fp, 0 ); //开启非阻塞模式
    fputs ( $fp, "GET " . $url . "\r\n" );
    fclose ( $fp );
    jeepc
        44
    jeepc  
       Jun 23, 2020   1
    <?php

    namespace app\util;


    class HttpUtils
    {


    /**
    * 异步执行
    * @param $host
    * @param $path
    * @param array $param
    * @return false|int|string
    */
    public static function requestAsync($host, $path, $param = array())
    {

    $query = isset($param) ? http_build_query($param) : '';

    $fp = @fsockopen($host);

    if (!$fp) {
    logError('连接失败');
    return 'connection error';
    }

    stream_set_blocking($fp, 0); //非阻塞
    stream_set_timeout($fp, 1);//响应超时时间( S )
    $out = "POST " . $path . " HTTP/1.1\r\n";
    $out .= "host:" . $host . "\r\n";
    $out .= "content-length:" . strlen($query) . "\r\n";
    $out .= "content-type:application/x-www-form-urlencoded\r\n";
    $out .= "connection:close\r\n\r\n";
    $out .= $query;

    $result = @fputs($fp, $out);

    @fclose($fp);
    return $result;

    }

    }

    <?php

    namespace app\api\controller;

    use app\util\HttpUtils;
    use think\Controller;
    use think\facade\Log;

    class Test extends Controller
    {
    public function test(){
    sleep(5);
    Log::record(1111);
    }

    public function testAsync(){

    HttpUtils::requestAsync($_SERVER['HTTP_HOST'],'/api/test/test');
    dump('return');
    }

    }

    仅供参考
    About     Help     Advertise     Blog     API     FAQ     Solana     4178 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 133ms UTC 05:19 PVG 13:19 LAX 22:19 JFK 01:19
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86