PHP-FPM与mysqlnd卡在连接上而不是超时(gdb回溯内部)
我正在运行
PHP-FPM,并且在极高负载时会出现问题,导致php进程永远陷入困境.我做了一个GDB回溯的运行进程被卡住了,得到了这个(删除了无关的帧):
#0 0x00007ff51704bb90 in __poll_nocancel () at ../sysdeps/unix/syscall-template.S:81 #1 0x0000000000694694 in poll (__timeout=<optimized out>,__nfds=1,__fds=0x7fff18a2c800) at /usr/include/x86_64-linux-gnu/bits/poll2.h:46 #2 php_pollfd_for (timeouttv=0x2c18a30,events=25,fd=<optimized out>) at /build/buildd/php5-5.5.19+dfsg/main/php_network.h:165 #3 php_sock_stream_wait_for_data (stream=0x2df2b88,sock=0x2c18a28) at /build/buildd/php5-5.5.19+dfsg/main/streams/xp_socket.c:131 #4 php_sockop_read (stream=0x2df2b88,buf=0x2e03628 "X221340 02",count=4) at /build/buildd/php5-5.5.19+dfsg/main/streams/xp_socket.c:154 #5 0x00000000004a629a in php_openssl_sockop_read (stream=0x2df2b88,count=<optimized out>) at /build/buildd/php5-5.5.19+dfsg/ext/openssl/xp_ssl.c:234 #6 0x0000000000688926 in _php_stream_fill_read_buffer (stream=stream@entry=0x2df2b88,size=size@entry=4) at /build/buildd/php5-5.5.19+dfsg/main/streams/streams.c:691 #7 0x0000000000688a87 in _php_stream_read (stream=stream@entry=0x2df2b88,buf=buf@entry=0x7fff18a2c9e0 "",size=size@entry=4) at /build/buildd/php5-5.5.19+dfsg/main/streams/streams.c:738 #8 0x00007ff5164b83a6 in php_mysqlnd_net_network_read_ex_pub (net=<optimized out>,buffer=<optimized out>,count=4,stats=0x2add010,error_info=<optimized out>) at /build/buildd/php5-5.5.19+dfsg/ext/mysqlnd/mysqlnd_net.c:80 #9 0x00007ff5164b7cb6 in php_mysqlnd_net_receive_ex_pub (net=0x2e04238,buffer=0x7fff18a2c9e0 "",conn_stats=0x2add010,error_info=0x2e13860) at /build/buildd/php5-5.5.19+dfsg/ext/mysqlnd/mysqlnd_net.c:682 #10 0x00007ff5164b118b in mysqlnd_read_header (net=0x2e04238,error_info=<optimized out>,header=<optimized out>,header=<optimized out>) at /build/buildd/php5-5.5.19+dfsg/ext/mysqlnd/mysqlnd_wireprotocol.c:287 #11 0x00007ff5164b1d46 in php_mysqlnd_greet_read (_packet=0x2e14e98,conn=0x2e13728) at /build/buildd/php5-5.5.19+dfsg/ext/mysqlnd/mysqlnd_wireprotocol.c:333 #12 0x00007ff5164ab8ad in php_mysqlnd_conn_data_connect_handshake_pub (conn=0x2e13728,host=<optimized out>,user=0x2b49d70 "testuser",passwd=0x2b49c40 "<PASSWORD REMOVED>",passwd_len=7,db=0x2b43c18 "testuser",db_len=7,mysql_flags=959117) at /build/buildd/php5-5.5.19+dfsg/ext/mysqlnd/mysqlnd.c:774 #13 0x00007ff5164a9e71 in php_mysqlnd_conn_data_connect_pub (conn=0x2e13728,host=0x2e13558 "localhost",port=3306,socket_or_pipe=0x7ff50a563b4c "/var/run/mysqld/mysqld.sock",mysql_flags=959117) at /build/buildd/php5-5.5.19+dfsg/ext/mysqlnd/mysqlnd.c:958 #14 0x00007ff5164a6430 in php_mysqlnd_conn_connect_pub (conn_handle=0x2e136d8,mysql_flags=131072) at /build/buildd/php5-5.5.19+dfsg/ext/mysqlnd/mysqlnd.c:1098 #15 0x00007ff5164adc07 in mysqlnd_connect (conn_handle=0x2e136d8,user=<optimized out>,passwd=<optimized out>,passwd_len=<optimized out>,db=<optimized out>,mysql_flags=131072) at /build/buildd/php5-5.5.19+dfsg/ext/mysqlnd/mysqlnd.c:1131 #16 0x00007ff50a55fe82 in mysqli_common_connect (ht=<optimized out>,return_value=0x2e05978,return_value_ptr=<optimized out>,this_ptr=<optimized out>,return_value_used=<optimized out>,is_real_connect=is_real_connect@entry=0 ' 00',in_ctor=in_ctor@entry=1 ' 01') at /build/buildd/php5-5.5.19+dfsg/ext/mysqli/mysqli_nonapi.c:242 #17 0x00007ff50a560633 in zif_mysqli_link_construct (ht=<optimized out>,return_value=<optimized out>,return_value_used=<optimized out>) at /build/buildd/php5-5.5.19+dfsg/ext/mysqli/mysqli_nonapi.c:320 所以我可以看到的是,我正在尝试连接到MySQL,然后PHP卡住轮询插件. MySQL可能会丢弃或拒绝连接(数据库处于100%cpu负载). 但是,我将mysql.connect_timeout设置为60,所以我希望连接不会持续很长时间(超过20分钟). default_socket_timeout也设置为300秒. 而且我会预先考虑升级到mysqli的任何建议,说我已经尝试过(我们使用的是DBAL),并且遇到了与mysqli使用相同连接功能相同的问题. 我在Ubuntu上运行PHP 5.5.19,并使用mysqlnd驱动程序. 知道什么可能导致PHP没有超时吗?
我认为你正在打我称之为“死亡可用性乐队”.这意味着你在你的行动完全失败(它会超时)和不起作用之间陷入困境.事情就是这样
>您调用PHP脚本 我意识到你不是在发送SQL,但我认为相同的原则会发挥作用.您有时可以看到这种情况发生在使用MySQL Workbench(执行查询但无法返回结果)的远程数据库中.因此,Workbench会挂起来等待永远不会发生的响应. 那么如何解决这个问题呢?实际上,你不能在PHP的编程层面. PHP API不会暴露足够的底层调用,以允许您识别出您陷入死区并终止连接.编写一个查找死区的脚本将始终存在终止其他良好进程的风险.你最好的选择(尽管我不愿意这么说)是支持你的MySQL并确保它有足够的资源来达不到100%.如果您与PHP / Apache共享一个服务器,那就是这种事情的配方.我注意到它很少发生在我们更大更好的系统上,因为我们将MySQL移动到它自己的实例.另外,请查看mysqltuner.它可以查看您的MySQL实例并建议配置调整以提高性能. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |