[提交缺陷]Swoole2.X版本提供PHP原生协程支持实践,Http请求部分的$httpclient-setDefer();该行出...

栏目: Java · 发布时间: 7年前

内容简介:[提交缺陷]Swoole2.X版本提供PHP原生协程支持实践,Http请求部分的$httpclient-setDefer();该行出...

背景:研究一下这个Swoole2.X(V2.0.8)的协程,于是试了一下Tcp/Mysql/Redis/Http(在一个以Http形式下,协程了:TcpServer配置、 Redis 配置、 Mysql 配置、Http,最后的接口返回时间以里面最长的那个为准,也就是一般是Mysql耗时最长,它就是最长的接口返回时间了。)一起上,Swoole顾问觉得要想性能高还得加上RPC,再就是在一些数据的Pack和Unpack性能上予以加强,以争取每个请求都非常快非常高效,一请求发现出现了段错误,最新版本出现小小的问题属于正常性况,关键是如何反馈问题,看了一下Swoole的Wiki是如何提Bug的连接,于是就试着提一个Bug吧,给其它用Swoole万一出现Coredump的兄弟们作一个示范,进行提Bug的和捕获相关的Coredump的输出,参考Swoole的Wiki,地址:https://wiki.swoole.com/wiki/page/10.html。

一、假如在你的项目中出现段错误,怎么办?重新编译打包Swoole的源码并打成RPm包,打开debug,参数是: --enable-debug ,如下:

swoole-php71-2.0.7.el7.x86_64.spec 打包./configure部分:

#./configure --with-php-config=%{php_bin}/php-config --enable-coroutine --enable-async-redis

./configure --with-php-config=%{php_bin}/php-config --enable-coroutine --enable-async-redis --enable-debug

二、Mysql部分做测试,加上用户权限,那个Tcp就用Swoole的示例打开9501端口,官网上有很简单的TcpServer样例(略),Mysql部分如下:

Mysql服务器上@101.200.*.135:

#mysql

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 93109

Server version: 8.0.0-dmr-log Source distribution

mysql> grant all privileges on test.* to swooleUser@10.51.*.34 identified by "test123";

Query OK, 0 rows affected, 1 warning (0.04 sec)

mysql> flush privileges;    

Query OK, 0 rows affected (0.01 sec)

@测试机器@123.57.*.183

#rpm -ql mysql-client-8.0.0-170523211353.el7.centos.x86_64

/usr/local/mysql/bin/mysql

#/usr/local/mysql/bin/mysql -h10.44.*.177 -uswooleUser -p

Enter password:

mysql> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| test               |

+--------------------+

2 rows in set (0.00 sec)

三、根据TcpServer配置、Redis配置、Mysql配置、Http(试着访问百度的Http页面),一般来讲都是Mysql慢,所以,它才是重点,代码如下:

coroutinemysql.php

<?php
$server = new Swoole\Http\Server("123.57.*.183", 9507, SWOOLE_BASE);
$server->set([
    'worker_num' => 1,
]);

$server->on('Request', function ($request, $response) {
    $tcpclient = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP);
    $tcpclient->connect('127.0.0.1', 9501,0.5);
    $tcpclient->send("hello world\n");

    $redis = new Swoole\Coroutine\Redis();
    $redis->connect('123.57.*.183', 6379);
    $redis->setDefer();
    $redis->get('key');

    $mysql = new Swoole\Coroutine\MySQL();
    $ret = $mysql->connect([
    'host' => '10.44.*.177',
    'port' => 3306,
        'user' => 'swooleUser',
        'password' => 'test123',
        'database' => 'test',
    ]);
    if ($ret == false) {
        $response->end("MySQL connect fail!");
        return;
    }
    $mysql->setDefer();
    $mysql->query('select sleep(1)');

    $httpclient = new Swoole\Coroutine\Http\Client('123.125.114.144', 80);
    $httpclient->setHeaders(['Host' => "baidu.com"]);
    $httpclient->set([ 'timeout' => 1]);
    $httpclient->setDefer();
    $httpclient->get('/');

    $tcp_res  = $tcpclient->recv();
    $redis_res = $redis->recv();
    $mysql_res = $mysql->recv();
    $http_res  = $httpclient->recv();

    $response->end('Test End');
});
$server->start();

四、按Swoole官方的Wiki教程,设置一下吐核,From: https://wiki.swoole.com/wiki/page/10.html :

#ulimit -c unlimited

五、启动对外提供的Http协议的9507端口访问进来后的多种协议并发的协程服务,如下:

#php  coroutinemysql.php

六、访问Http时再触发一下协程:

触发一下:http://123.57.*.183:9507/

七、生成了段错误的Coredump文件,如下:

#php  coroutinemysql.php

段错误(吐核)

#ls *core*              

core.8494

八、用GDB去跟进其堆栈,BT显示调用层级定位出现问题所在位置:

#gdb php /tmp/core.8494

(gdb) bt

#0  0x00007f146b33e9a5 in http_client_coro_send_http_request (zobject=0x7f147248d190)

at /home/test/rpmbuild/BUILD/swoole-src-2.0.7-stable/swoole_http_client_coro.c:501

#1  0x00007f146b383c93 in swClient_onWrite (reactor=<optimized out>, event=0x7ffd0c185a10)

at /home/test/rpmbuild/BUILD/swoole-src-2.0.7-stable/src/network/Client.c:1109

#2  0x00007f146b37d63c in swReactorEpoll_wait (reactor=0x1dfc338, timeo=<optimized out>)

at /home/test/rpmbuild/BUILD/swoole-src-2.0.7-stable/src/reactor/ReactorEpoll.c:270

#3  0x00007f146b389de9 in swReactorProcess_loop (pool=<optimized out>,

worker=worker@entry=0x7ffd0c185ae0)

at /home/test/rpmbuild/BUILD/swoole-src-2.0.7-stable/src/network/ReactorProcess.c:379

#4  0x00007f146b38a727 in swReactorProcess_start (serv=serv@entry=0x1dc7cf0)

at /home/test/rpmbuild/BUILD/swoole-src-2.0.7-stable/src/network/ReactorProcess.c:112

#5  0x00007f146b381538 in swServer_start (serv=serv@entry=0x1dc7cf0)

at /home/test/rpmbuild/BUILD/swoole-src-2.0.7-stable/src/network/Server.c:696

#6  0x00007f146b333730 in zim_swoole_http_server_start (execute_data=0x7f14724130a0,

return_value=0x7ffd0c185cb0)

at /home/test/rpmbuild/BUILD/swoole-src-2.0.7-stable/swoole_http_server.c:1567

#7  0x00000000008ad0c6 in ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER ()

#8  0x000000000085bd3b in execute_ex ()

#9  0x00000000008aee24 in zend_execute ()

#10 0x0000000000816fc4 in zend_execute_scripts ()

#11 0x00000000007b8520 in php_execute_script ()

#12 0x00000000008b0fbf in do_cli ()

#13 0x000000000043d450 in main ()

(gdb)f 1

#1  0x00007f146b383c93 in swClient_onWrite (reactor=<optimized out>, event=0x7ffd0c185a10)

at /home/test/rpmbuild/BUILD/swoole-src-2.0.7-stable/src/network/Client.c:1109

1109                cli->onConnect(cli);

(gdb)f 0

#0  0x00007f146b33e9a5 in http_client_coro_send_http_request (zobject=0x7f147248d190)

at /home/test/rpmbuild/BUILD/swoole-src-2.0.7-stable/swoole_http_client_coro.c:501

501         if (!http->cli || !http->cli->socket )

九、用valgrind大体排查一下是否有内存溢出等:

[root@测试服务器:/tmp]

#USE_ZEND_ALLOC=0 valgrind php coroutinemysql.php

==12833== Memcheck, a memory error detector

==12833== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.

==12833== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info

==12833== Command: php coroutinemysql.php

==12833==

==12833== Invalid read of size 8

==12833==    at 0x121249A5: http_client_coro_send_http_request (swoole_http_client_coro.c:501)

==12833==    by 0x12169C92: swClient_onWrite (Client.c:1109)

==12833==    by 0x1216363B: swReactorEpoll_wait (ReactorEpoll.c:270)

==12833==    by 0x1216FDE8: swReactorProcess_loop (ReactorProcess.c:379)

==12833==    by 0x12170726: swReactorProcess_start (ReactorProcess.c:112)

==12833==    by 0x12167537: swServer_start (Server.c:696)

==12833==    by 0x1211972F: zim_swoole_http_server_start (swoole_http_server.c:1567)

==12833==    by 0x8AD0C5: ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER (in /usr/local/php/bin/php)

==12833==    by 0x85BD3A: execute_ex (in /usr/local/php/bin/php)

==12833==    by 0x8AEE23: zend_execute (in /usr/local/php/bin/php)

==12833==    by 0x816FC3: zend_execute_scripts (in /usr/local/php/bin/php)

==12833==    by 0x7B851F: php_execute_script (in /usr/local/php/bin/php)

==12833==  Address 0x100000188 is not stack'd, malloc'd or (recently) free'd

==12833==

==12833==

==12833== Process terminating with default action of signal 11 (SIGSEGV): dumping core

==12833==  Access not within mapped region at address 0x100000188

==12833==    at 0x121249A5: http_client_coro_send_http_request (swoole_http_client_coro.c:501)

==12833==    by 0x12169C92: swClient_onWrite (Client.c:1109)

==12833==    by 0x1216363B: swReactorEpoll_wait (ReactorEpoll.c:270)

==12833==    by 0x1216FDE8: swReactorProcess_loop (ReactorProcess.c:379)

==12833==    by 0x12170726: swReactorProcess_start (ReactorProcess.c:112)

==12833==    by 0x12167537: swServer_start (Server.c:696)

==12833==    by 0x1211972F: zim_swoole_http_server_start (swoole_http_server.c:1567)

==12833==    by 0x8AD0C5: ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER (in /usr/local/php/bin/php)

==12833==    by 0x85BD3A: execute_ex (in /usr/local/php/bin/php)

==12833==    by 0x8AEE23: zend_execute (in /usr/local/php/bin/php)

==12833==    by 0x816FC3: zend_execute_scripts (in /usr/local/php/bin/php)

==12833==    by 0x7B851F: php_execute_script (in /usr/local/php/bin/php)

==12833==  If you believe this happened as a result of a stack

==12833==  overflow in your program's main thread (unlikely but

==12833==  possible), you can try to increase the size of the

==12833==  main thread stack using the --main-stacksize= flag.

==12833==  The main thread stack size used in this run was 8388608.

==12833==

==12833== HEAP SUMMARY:

==12833==     in use at exit: 22,357,752 bytes in 22,711 blocks

==12833==   total heap usage: 29,852 allocs, 7,141 frees, 23,257,973 bytes allocated

==12833==

==12833== LEAK SUMMARY:

==12833==    definitely lost: 64 bytes in 2 blocks

==12833==    indirectly lost: 4,096 bytes in 2 blocks

==12833==      possibly lost: 1,813,286 bytes in 18,399 blocks

==12833==    still reachable: 20,540,306 bytes in 4,308 blocks

==12833==         suppressed: 0 bytes in 0 blocks

==12833== Rerun with --leak-check=full to see details of leaked memory

==12833==

==12833== For counts of detected and suppressed errors, rerun with: -v

==12833== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

段错误

十、在 PHP 代码上加加减减,定位一下PHP这个协程是哪个协议出现问题,经定位发现是发起http这块的协程可能有问题,如下:

再细节一点:

#php coroutinemysql.php

段错误(吐核)

这一行引起的:$httpclient->setDefer();     #setDefer函数的Wiki地址:https://wiki.swoole.com/wiki/page/607.html

$httpclient = new Swoole\Coroutine\Http\Client('123.125.114.144', 80);

$httpclient->setHeaders(['Host' => "baidu.com"]);

$httpclient->set([ 'timeout' => 3]);

$httpclient->setDefer();            #注释这一行,就会报下面的警告,不会Coredump,如下:                                                                

$httpclient->get('/');

#php coroutinemysql.php   #浏览器访问一下:http://123.57.*.183:9507/

PHP Warning:  Swoole\Coroutine\Http\Client::recv(): you should not use recv without defer  in /tmp/coroutinemysql.php on line 40

PHP Warning:  Swoole\Coroutine\Http\Client::recv(): you should not use recv without defer  in /tmp/coroutinemysql.php on line 40

在服务器上CURL形式访问一下百度,没毛病:

curl -i -H"Host:baidu.com" http://123.125.114.144            

HTTP/1.1 200 OK  

<html>

<meta http-equiv=refresh content=0;url=http://www.baidu.com/>

</html>

十一、提交出现Coredump以及和环境相关的问题给Swoole的CoreTeam研发小组的兄弟:

请将上面的得到的信息,连同机器信息,包括php -v gcc -v uname -a 提交到Github Issues页面或者发送邮件到 team@swoole.com。

若确定是Swoole的问题,开发组会快速解决问题。

其它涉及到编译器和PHP版本、系统环境:

#php -v

PHP 7.1.5 (cli) (built: May 23 2017 10:35:57) ( NTS )

Copyright (c) 1997-2017 The PHP Group

Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies

with Zend OPcache v7.1.5, Copyright (c) 1999-2017, by Zend Technologies

#gcc -v

使用内建 specs。

COLLECT_GCC=gcc

COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper

目标:x86_64-redhat-linux

配置为:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux

线程模型:posix

gcc 版本 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC)

#uname -a

Linux 测试服务器 4.11.2-1.el7.elrepo.x86_64 #1 SMP Sun May 21 19:31:34 EDT 2017 x86_64 x86_64 x86_64 GNU/Linux

#php --ri swoole

swoole

swoole support => enabled

Version => 2.0.8

Author => tianfeng.han[email: mikan.tenny@gmail.com]

epoll => enabled

eventfd => enabled

timerfd => enabled

signalfd => enabled

cpu affinity => enabled

spinlock => enabled

rwlock => enabled

async redis client => enabled

async http/websocket client => enabled

Linux Native AIO => enabled

pcre => enabled

zlib => enabled

mutex_timedlock => enabled

pthread_barrier => enabled

Directive => Local Value => Master Value

swoole.aio_thread_num => 2 => 2

swoole.display_errors => On => On

swoole.use_namespace => On => On

swoole.fast_serialize => 1 => 1

swoole.unixsock_buffer_size => 8388608 => 8388608

EOF


以上所述就是小编给大家介绍的《[提交缺陷]Swoole2.X版本提供PHP原生协程支持实践,Http请求部分的$httpclient-setDefer();该行出...》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Blockchain Basics

Blockchain Basics

Daniel Drescher / Apress / 2017-3-16 / USD 20.99

In 25 concise steps, you will learn the basics of blockchain technology. No mathematical formulas, program code, or computer science jargon are used. No previous knowledge in computer science, mathema......一起来看看 《Blockchain Basics》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具