文档章节

PHP异步的玩法

乱蓬头
 乱蓬头
发布于 2017/05/19 14:11
字数 1525
阅读 6
收藏 0
点赞 0
评论 0

摘要: PHP是世界上最好的语言,但是总被“同行们”吐槽不支持异步。其实我们要实现异步也非常简单,之前看到鸟哥的一篇写PHP异步执行的博文 PHP实现异步调用方法研究,这篇文章还是08年的,到今天PHP发展快10年了,对于异步调用也有了更多新的玩法。

PHP是世界上最好的语言,但是总被“同行们”吐槽不支持异步。其实我们要实现异步也非常简单,之前看到鸟哥的一篇写PHP异步执行的博文 PHP实现异步调用方法研究,这篇文章还是08年的,到今天PHP发展快10年了,对于异步调用也有了更多新的玩法。

一. 先说说鸟哥文章中的几种玩法:

  1. 一是通过渲染前端页面,使用js执行Ajax,这种方式现在还适用。只是受限于业务场景,因为只能在浏览器中调用,遇到接口请求就不行了。

  2. 二是通过popen()方法打开一个指向进程的管道,每个请求会多起一个进程。忽略进程来看最主要的原因是数据的传输特别不方便,使用场景有限。

  3. 三是使用CURL扩展,通过设置timeout超时参数,能实现离弦之箭的效果。不过这种方法会主动断开连接。被调用的服务如果有做连接检测,也会中断服务端脚本的执行。比如我们请求 微信的某个费时接口(20s),我们调用1s就断开连接,微信端是否会维持请求执行20S是不可控的。所以这种方法不推荐大家使用。

  4. 四方法与CURL类似,通过fsockopen创建socket连接访问远程服务,不循环获取请求结果。一样会有三中连接被断开的问题。

二. PHP发展了这么多年对异步支持方面都有哪些改进?

  1. CURL扩展已支持毫秒配置,将 CURLOPT_TIMEOUT 改为 CURLOPT_TIMEOUT_MS 即可生效(cURL 版本 >= libcurl/7.21.0,老服务器要检查版本),但还是我前面说的需要服务端配合,不然接口的调用结果不可控。

  2. CURL扩展已支持并发,我们能一次访问N个接口,执行时间取最长接口的时间。比如我们能一次访问 京东支付(1s),微信支付(1.2s),支付宝(0.8s)不同服务的三个接口,总耗时才1.2s。详细用法 curl_multi_init

  3. 类似Node.js的异步IO框架Swoole,能很好的实现异步调用;不过Swoole理论上不能算PHP框架,他算是PHP功能的扩展。所以除非项目都用Swoole写,不然也是享受不到异步IO的福利。

  4. 对yield的支持,能实现调度器的功能,写单进程的服务时能大展拳脚,特别是实现协程,异步更不在话下。不过在多进程的web服务上没有太大的使用场景,看未来会不会有新的玩法吧。

当然还有很多新的特性,这里不再细说,总之PHP越是被黑越是能快速发展。

三. 最好的异步实现方法

我们都知道PHP是支持多进程编程的,那完全可以新建一个进程去实现异步的调用。比如调用popen()方法,但是管道的方式传参异常麻烦,不过多进程这个方法是绝对可行的。如果要实现多进程的功能,毫无疑问我们会选择PHP官方提供的 pcntl 扩展,PHP默认会安装pcntl扩展,如果代码运行提示找不到pcntl扩展,可自行到php-src下载,选择好版本通过phpize安装即可。代码如下

<?php
/**
 * User: layne.xfl
 * Date: 2017/5/12
 * Time: 下午01:24
 */
class Arrow{

    static $instance;

    /**
     * @return static
     */
    public static function getInstance(){
        if (null == Arrow::$instance)
            Arrow::$instance = new Arrow();
        return Arrow::$instance;
    }

    public function run($rb){

        $pid = pcntl_fork();
        if($pid > 0){
            pcntl_wait($status);
        }elseif($pid == 0){
            $cid = pcntl_fork();
            if($cid > 0){
                //这里放空
            }elseif($cid == 0){
                $rb();
            }else{
                exit();
            }
        }else
        {
           exit();
        }

    }
}
//离弦之箭---调用方法
$time_out = 30;
Arrow::getInstance()->run(function() use ($time_out){
    //这里写我们要执行的代码
    sleep($time_out);
});

我给这个功能取了一个很生动的名字--离弦之箭。代表异步调用,我们的弓箭射出去后并不关心它的结果因为发送这个动作做了就行。比如打个10M的log,通知10个人(发10条短信)。

代码说明:首先Arrow类是个单例类,减少多次调用的开销。run()方法传递的是一个匿名函数,这样我们能非常方便的传递参数,并且保留上下文。

这个类最难的地方在于多进程的处理。因为我们要尽可能快的将数据返回给用户,所以主进程越快结束越好。但是我们又需要子进程来执行我们耗时的操作,执行完退出才行。如果不等子进程执行完就将父进程退出会出现什么结果呢?结果就是子进程会常驻内存变成僵死进程。那我们有什么办法让子进程执行完之后就自动结束呢?答案是很难……那么儿子进程这么不听话,孙子进程会不会听话一点呢??答案是孙子进程执行结束后会被系统进程回收并销毁(还是孙子听话)。所以我在代码中使用了如下方法:当前请求进程fork出子进程,子进程fork出孙子进程,主进程和子进程都先行退出,最后由孙子进程来执行耗时操作,最后完美的解决了僵死进程问题。

当然这个方法的缺点就是调用的时候会多产生一个php-fpm的进程。关于php-fpm进程的管理和规划又是另一个话题了。扩展阅读 PHP进程间通信

本文转载自:http://click.aliyun.com/m/21446/

共有 人打赏支持
乱蓬头
粉丝 0
博文 382
码字总数 2595
作品 0
Nginx版UPUPW PHP环境集成包UP-N2发布

Nginx版UPUPW PHP环境集成包UP-N2采用最新发布的Discuz!X3.0作为测试对象针对PHP运行环境进行开发,完美驱动Discuz!X3.0等PHP程序的运行、负载、缓存等! 一直以来默默为中国站长提供动力的C...

UPUPW
2013/05/15
2.3K
35
PHP.net 服务器发现盗版电影

PHP.net是世界著名的PHP语言的官方网站,不过这个网站背后的管理员似乎确实有用服务器下片的玩法,SEO人士Whistlerblower Stephen Chapman发现,PHP.net的服务器上竟然有盗版的电影,并且管理...

1001
2011/09/02
4K
17
【只剩1天】听云为PHP/Java开发者,送卫衣!送手办

PHP是世界上最好的语言! 活动,肿么能不带上Java开发者一起玩呢?不科学! 即日起至11月12日(是滴活动周期也延长了)! 通过account.tingyun.com/reg/register?userFrom=oschina新注册听云...

听云APM
2015/10/24
5.6K
80
新版拉菲×××彩票源码(ThinkPHP内核开发-HTML5全屏自适应带开奖软件+WAP独立端)

程序源码参数说明: 1.龙虎和玩法可以同时下注 2.可定制玩法 3.这套非天恒后台,可以改单撤单 4.2/5分彩后台手动输入盈亏率 5.前台下拉奖金返点,简单方便 运行环境:php5.2+mysql 源码授权:...

asgsfhgsh
07/06
0
0
node爬虫获取漫威超级英雄电影海报

昨天去看了《复联3》的首映,当我提前15分钟进入影院的时候, 看到了粉丝们取票的长队, 顿时有一种跨年夜的感觉... 最近看了node爬虫的一些知识, 这里用node爬取一下漫威官网的电影海报! 小结:...

木子昭
05/12
0
0
git add OSC招聘-那些小而美的公司第二期

大家一般都在下午3点左右上开源中国招聘找工(shi)作(ye),高峰期常常落在周三,小编我都看着呢。而且,程序员连找工作都是有双休的。周末访问量相对工作日会低很多。这叫程序员找工作正态分布...

oschina
2016/03/01
3.8K
10
【腾讯云的1001种玩法】微信个人订阅号后台server搭建入门教程

搭建公众号后台server 以腾讯云自带的ubuntu14.04为例: 1.安装nginx+php7+mysql5,以及需要的扩展; 由于ubuntu14.04默认软件库为php5,需要加入第三方库,来apt-get方式安装PHP7; 当然,也...

2017/12/18
0
0
好的技术人员一定要懂业务 -- 这是一个新问题

@红薯 , 这是新的玩法 技术之选型等其实要求很高, 并且是根据业务需求来做的。 在不懂业务的前提下,号称 懂构架,懂技术, 就一定是扯蛋 那种技术“大牛”就是只会产生Bullshit的大牛 我反...

宏哥
2015/11/27
270
0
记一次 skynet 中使用 skynet.queue 给消息加锁时的问题

应该大多数 skynet 项目都是以 Lua 作为主开发语言。在使用 Lua 编写 skynet 服务时,基本的执行单元是 coroutine 。当有消息到达使用 Lua 编写的服务时,skynet 都会起一个 coroutine 来处理...

ylme
03/24
0
0
PHP的异步并行扩展Swoole已收录到PHP官方扩展库

PHP的异步并行扩展Swoole已收录到PHP官网扩展库pecl.php.net。最新的版本是swoole-1.6.9。国内程序员组织的开源PHP扩展项目,能够添加到pecl中的并不多,目前仅有yaf,yar,yac,swoole等数个。...

matyhtf
2014/01/17
11.9K
14

没有更多内容

加载失败,请刷新页面

加载更多

下一页

设计神器 - 摹客设计系统上线了 | 晒出你的设计规范,赢iPad Pro!

在国内,设计规范也许还是个不太常用的概念,但是如果你正好有参与互联网公司的产品设计,你应该早就已经体会到设计规范的重要性了。UI设计师总是要花费大量的时间和精力向开发描述一大堆设计...

mo311
4分钟前
0
0
Thymeleaf 使用过程中的一些记录

Thymeleaf格式化时间: th:value="${#dates.format(gw.regDT,'yyyy-MM-ddHH:mm:ss')}" Thymeleaf select反选: <select id="status" name="status" th:field="${gw.status}" th:value="${gw.......

惊尘大人
7分钟前
0
0
istio源码分析之pilot-discovery模块分析

本文分析的istio代码版本为0.8.0,commit为0cd8d67,commit时间为2018年6月18日。 本文为Service Mesh深度学习系列之一: Service Mesh深度学习系列part1—istio源码分析之pilot-agent模块分...

xiaomin0322
12分钟前
0
0
数据库基本操作:增删改查及联表操作

所用软件:SQL Server Management Studio 首先第一步,建立一个表。在这里命名为T1。并在里面填入几条数据。如图: T1 一.查询 查询所有:select * from T1; 按条件查询:select * from T1 ...

小_橙_子
16分钟前
0
0
Crontab作业时间设置

今天,遇到这么一个题目,周一到周五的9:00-16:59之间,每隔两分钟将某个命令运行一次。给的答案是: */2 9-16 * * 1-5 /usr/sbin/somecommand dosomething 乍一看,这个答案不对,应...

大别阿郎
21分钟前
0
0
ES17-JAVA API文档管理

1.保存文档 可以通过json工具把java对象转换成json字符串进行保存,也可以通过内置的帮助类直接构建json格式 /** * 获取客户端 * * @return */public static TransportClie...

贾峰uk
21分钟前
0
0
Python代码规范和命名规范

前言 Python 学习之旅,先来看看 Python 的代码规范,让自己先有个意识,而且在往后的学习中慢慢养成习惯 一、简明概述 1、编码 如无特殊情况, 文件一律使用 UTF-8 编码 如无特殊情况, 文件头...

blackfoxya
24分钟前
0
0
联动滑动之一:NestScrollChild和NestedScrollingParent

NestScrollChild和NestedScrollingParent 吐槽一下开源中国竟然标题字数有限制 由于项目中使用了CoordinateLayout来解决联动以及实现炫酷的UI效果,那么必须就要研究一波源码了,毕竟知其然知...

JerryLin123
41分钟前
1
0
cloudera spark2.2 读写hbase

cloudera spark2.2 读写hbase 例子 host = 'bigdata-03,bigdata-05,bigdata-04'conf = { "hbase.zookeeper.quorum": host, "hbase.mapreduce.inputtable": "student1"}k......

osenlin
46分钟前
0
0
数据库规范化

转载自 一个小时学会MySQL数据库 地址:http://www.cnblogs.com/best/p/6517755.html 截取其中 1.4 部分 用于自己学习使用 感谢作者:张果 1.4、数据库规范化 经过一系列的步骤,我们现在终于...

十万猛虎下画山
47分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部