php curl tls 版本_Swoole 4.4:支持 CURL 协程化

fc5049cebedfc8f03efe1daa12c049f5.gif

本文原载于SegmentFault专栏“Swoole”

作者:韩天峰

整理编辑:SegmentFault

4.4之前的版本中,Swoole一直不支持CURL协程化,在代码中无法使用curl。由于curl使用了libcurl库实现,无法直接hook它的socket4.4版本使用Swoole\Coroutine\Http\Client模拟实现了curlAPI,并在底层替换了curl_init等函数的C Handler

提示

  • CURL Hook的特性尚处于试验阶段,请勿在生产环境中直接使用

  • 暂不支持文件上传、CURL Multi

  • 仍然需要依赖curl,请务必安装curl扩展

支持的特性列表

  • GET/POST

  • Header

  • Cookie

  • Https

经过验证 Guzzle CURL完全可以使用

开启

使用Runtime::enableCoroutine来开启CURL Hook

默认不开启 CURL Hook
Swoole\Runtime::enableCoroutine(SWOOLE_HOOK_ALL);Swoole\Runtime::enableCoroutine(SWOOLE_HOOK_CURL);

使用

$n = 10;while($n--) {
        go(function () {
            $ch = curl_init();        curl_setopt($ch, CURLOPT_URL, "http://www.xinhuanet.com/");        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);        curl_setopt($ch, CURLOPT_HEADER, 0);        $output = curl_exec($ch);        if ($output === FALSE) {
                echo "CURL Error:" . curl_error($ch);        }        curl_close($ch);        echo strlen($output) . " bytes\n";    });}
要将上面两段代码合并到一个文件中执行

运行结果

htf@LAPTOP-0K15EFQI:~/swoole-src/examples$ time php curl.php177173 bytes177173 bytes177173 bytes177173 bytes177173 bytes177173 bytes177173 bytes177173 bytes177173 bytes177173 bytesreal    0m0.534suser    0m0.031ssys     0m0.297s

可以看到整个程序是并行的,进程没有任何阻塞。

strace 跟踪

使用strace跟踪发现,所有系统调用均变成epoll+socket的异步非阻塞调用了。

epoll_create(512)                       = 3mmap(NULL, 258048, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc038a50000mmap(NULL, 2101248, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc028910000socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_IP) = 4fcntl(4, F_GETFL)                       = 0x80002 (flags O_RDWR|O_CLOEXEC)fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK|O_CLOEXEC) = 0setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0pipe([5, 6])                            = 0fcntl(5, F_GETFL)                       = 0 (flags O_RDONLY)fcntl(5, F_SETFL, O_RDONLY|O_NONBLOCK)  = 0fcntl(6, F_GETFL)                       = 0x1 (flags O_WRONLY)fcntl(6, F_SETFL, O_WRONLY|O_NONBLOCK)  = 0epoll_ctl(3, EPOLL_CTL_ADD, 5, {EPOLLIN, {u32=5, u64=34359738373}}) = 0mmap(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7fc028100000mprotect(0x7fc028101000, 8388608, PROT_READ|PROT_WRITE) = 0clone(child_stack=0x7fc0288ffb70, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7fc0289009d0, tls=0x7fc028900700, child_tidptr=0x7fc0289009d0) = 55mmap(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7fc0237f0000mprotect(0x7fc0237f1000, 8388608, PROT_READ|PROT_WRITE) = 0clone(child_stack=0x7fc023fefb70, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7fc023ff09d0, tls=0x7fc023ff0700, child_tidptr=0x7fc023ff09d0) = 56mmap(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7fc022fe0000mprotect(0x7fc022fe1000, 8388608, PROT_READ|PROT_WRITE) = 0clone(child_stack=0x7fc0237dfb70, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7fc0237e09d0, tls=0x7fc0237e0700, child_tidptr=0x7fc0237e09d0) = 57mmap(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7fc0227d0000mprotect(0x7fc0227d1000, 8388608, PROT_READ|PROT_WRITE) = 0clone(child_stack=0x7fc022fcfb70, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7fc022fd09d0, tls=0x7fc022fd0700, child_tidptr=0x7fc022fd09d0) = 58futex(0x7fffd9e01ce0, FUTEX_WAKE_PRIVATE, 1) = 1clock_gettime(CLOCK_MONOTONIC, {tv_sec=232, tv_nsec=513190000}) = 0clock_gettime(CLOCK_MONOTONIC, {tv_sec=232, tv_nsec=513408000}) = 0mmap(NULL, 2101248, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc0225c0000socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_IP) = 8fcntl(8, F_GETFL)                       = 0x80002 (flags O_RDWR|O_CLOEXEC)fcntl(8, F_SETFL, O_RDWR|O_NONBLOCK|O_CLOEXEC) = 0setsockopt(8, SOL_TCP, TCP_NODELAY, [1], 4) = 0futex(0x7fffd9e01ce0, FUTEX_WAKE_PRIVATE, 1) = 1clock_gettime(CLOCK_MONOTONIC, {tv_sec=232, tv_nsec=514359000}) = 0mmap(NULL, 2101248, P
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值