zoukankan      html  css  js  c++  java
  • 原生PHP代码实现耗时任务后台异步伪并发执行

    目前已在公司项目中完美使用,应用场景仅适合NGINX+PHP-FPM。APACHE FCGI模式未测试。伪并发执行指NGINX给FPM子进程分配任务时,可以多个进程实现同时工作,并非处理高并发请求。

    // 设置客户端断开连接时不中断脚本的执行
    ignore_user_abort(true);
     
    // 以下代码开始告诉NGINX响应已经成功得到响应内容可以关闭请求了。
    # 擦除缓冲区的内容并关闭,然后在启动新的ob缓冲
    ob_end_clean(); ob_start();
    # 输出响应数据,这里模拟输出json。320:中文不编码+不转移斜杠[JSON_UNESCAPED_UNICODE + JSON_UNESCAPED_SLASHES] = 320
    echo json_encode(['status' => true, 'message' => '任务开始执行', 'date' => null], 320);
    $size = ob_get_length();
    # 响应内容长度
    header("Content-Length: $size");
    # 告诉NGINX可以关闭http连接了
    header("Connection: close");
    # 此次请求已收到并正常处理
    header("HTTP/1.1 200 OK");
     
    # 刷新输出缓冲区内容并关闭ob缓冲
    ob_end_flush(); 
    # 如果缓冲区还有内容,再次刷新输出ob缓冲块的内容
    ob_get_length() && ob_flush();
    # 再次刷新输出,冲刷Web Server的缓冲区。例如用于防范NGINX GZIP或 APACHE mod_gzip自己的缓冲区
    flush();
    # 冲刷所有响应的数据给客户端。
    function_exists("fastcgi_finish_request") && fastcgi_finish_request();
    session_write_close(); # 关闭session写入,取消对session进行IO的锁
     
    // 设置最大执行时间,这里为15分钟
    ini_set('max_execution_time', 15 * 60);
    set_time_limit(15 * 60);
    // 额外设置
    error_reporting(0); # 屏蔽所有报告异常
    ini_set('memory_limit', '512M'); # 临时设置内存,若默认运行内存128M够用,无需再次设置
    date_default_timezone_set('Asia/Shanghai'); # 时区
     
    // code ...
    // error_log('任务执行完成'); UPDATE TABLE ...
     
    exit;
    

    为何要冲刷那么多次缓冲区?

    PHP的数据写入顺序: ob_start(),将内部缓冲区(buffer)打开。当PHP遇到echo,printf等输出语句时,PHP就会将要输出的数据放入缓冲区(buffer)中,等待输出。而只有当缓冲区满了或者PHP运行完毕,才将数据输出去。输出字节离开PHP缓冲区进去Apache缓冲区或者Nginx缓冲区(fast-cgi),之后进入浏览器缓冲区。

    注意:此代码不适合高并发请求大耗时任务巨长的工作

    因FPM子进程工作满载中,NGINX无法分配任务,以至于任务不能及时处理,造成NGINX报出502错误,导致任务处理失败。这种场景可选择开启更多的NGINX WORKER进程和更多的FPM子进程,或使用其它解决方案。

  • 相关阅读:
    IP 协议
    以太网协议
    制作Win10系统安装U盘和安装纯净版Win10
    IP地址的配置
    进制转换
    设置QQ环境变量
    修改IE默认页的指向
    虚拟机安装Linux ubuntu19.10
    【Eclipse】Editor does not contain a main type
    Vmware Workstation虚拟机
  • 原文地址:https://www.cnblogs.com/qiutianjia/p/11573377.html
Copyright © 2011-2022 走看看