PHP – зависание curl_exec

У меня возникла странная проблема с приведенной ниже функцией php. К сожалению, это один из тех специальных случаев «Только производство».

function requestPost($url, $data) { set_time_limit(60); $output = array(); $curlSession = curl_init(); if($curlSession == false) syslog(LOG_INFO,"Falied to create a curl sessions"); // Set the URL curl_setopt ($curlSession, CURLOPT_URL, $url); // No headers, please curl_setopt ($curlSession, CURLOPT_HEADER, 0); // It's a POST request curl_setopt ($curlSession, CURLOPT_POST, 1); // Set the fields for the POST curl_setopt ($curlSession, CURLOPT_POSTFIELDS, $data); // Return it direct, don't print it out curl_setopt($curlSession, CURLOPT_RETURNTRANSFER,1); // This connection will timeout in 30 seconds curl_setopt($curlSession, CURLOPT_TIMEOUT,30); //The next two lines must be present for the kit to work with newer version of cURL //You should remove them if you have any problems in earlier versions of cURL curl_setopt($curlSession, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curlSession, CURLOPT_SSL_VERIFYHOST, 1); //Send the request and store the result in an array syslog(LOG_INFO,"base.php::requestPost() : BEFORE SENDING CURL "); $rawresponse = curl_exec($curlSession); } 
 PHP 5.3.6 (cli) (built: Mar 17 2011 21:19:28) curl Version : 7.20.1 NSS Version : 3.12.9 apr Version : 1.4.5 Php Version : 5.3.6 

Кажется, это зависает в curl_exec случайно. Я не разработчик php, поэтому я понятия не имею, с чего начать.

Я заметил, что, когда запросы на завивание «зависают», при остановке демона httpd он пытается отправить эти запросы, поэтому может показаться, что они получают буферизацию или застревание на сервере httpd. Любые указатели будут оценены.

Изменить: мне удалось получить трассировку стека из веб-сервера.

 (gdb) where #0 0x00c15416 in __kernel_vsyscall () #1 0x002f522c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libpthread.so.0 #2 0x00a73a9d in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libc.so.6 #3 0x00b9b869 in PR_WaitCondVar () from /lib/libnspr4.so #4 0x00809c0f in NSSRWLock_LockWrite_Util () from /usr/lib/libnssutil3.so #5 0x05e9ae0e in ?? () from /usr/lib/libnss3.so #6 0x05ebd014 in ?? () from /usr/lib/libnss3.so #7 0x05ebd60d in ?? () from /usr/lib/libnss3.so #8 0x05eb0506 in SECMOD_LoadModule () from /usr/lib/libnss3.so #9 0x05eb047f in SECMOD_LoadModule () from /usr/lib/libnss3.so #10 0x05e7c007 in ?? () from /usr/lib/libnss3.so #11 0x05e7c95e in NSS_Initialize () from /usr/lib/libnss3.so #12 0x008e8609 in ?? () from /usr/lib/libcurl.so.4 #13 0x008e9215 in Curl_nss_connect () from /usr/lib/libcurl.so.4 #14 0x008df9a3 in Curl_ssl_connect () from /usr/lib/libcurl.so.4 #15 0x008bc1fa in Curl_http_connect () from /usr/lib/libcurl.so.4 #16 0x008c44c6 in Curl_protocol_connect () from /usr/lib/libcurl.so.4 #17 0x008c5075 in ?? () from /usr/lib/libcurl.so.4 #18 0x008c58cf in Curl_async_resolved () from /usr/lib/libcurl.so.4 #19 0x008d1b2f in Curl_perform () from /usr/lib/libcurl.so.4 #20 0x008d2a74 in curl_easy_perform () from /usr/lib/libcurl.so.4 #21 0x006b4693 in ?? () from /usr/lib/php/modules/curl.so #22 0x056e4ac9 in ?? () from /etc/httpd/modules/libphp5.so #23 0x056bb87e in execute () from /etc/httpd/modules/libphp5.so #24 0x05693a66 in zend_execute_scripts () from /etc/httpd/modules/libphp5.so #25 0x05639cb6 in php_execute_script () from /etc/httpd/modules/libphp5.so #26 0x057236b3 in ?? () from /etc/httpd/modules/libphp5.so #27 0x00dc6421 in ap_run_handler () #28 0x00dca166 in ap_invoke_handler () #29 0x00dd6fa8 in ap_process_request () #30 0x00dd39e8 in ?? () #31 0x00dcec71 in ap_run_process_connection () #32 0x00ddc44a in ?? () #33 0x00ddc7ee in ?? () #34 0x00ddd793 in ap_mpm_run () #35 0x00db0ab2 in main () 

Кажется, он застрял в состоянии ожидания pthread_condition. У кого-нибудь есть ключ ? Один и тот же запрос успешно выполняется каждый раз через командную строку; поэтому он указывает на библиотеки.

Редактировать:

Ниже приведен призыв, от которого он никогда не выходит.

 * About to connect() to live.sagepay.com port 443 (#0) * Trying xxxx.. * connected * Connected to live.sagepay.com (xxxx) port 443 (#0) * warning: ignoring unsupported value (1) of ssl.verifyhost * CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath: none * SSL connection using SSL_RSA_WITH_RC4_128_MD5 * Server certificate: * subject: CN=live.sagepay.com,OU="Member, VeriSign Trust Network",OU=Authenticated by VeriSign,OU=Terms of use at www.verisign.co.uk/rpa (c)05,OU=Sage,O=Sage (UK) Limited,L=Newcastle Upon Tyne,ST=TYNE AND WEAR,C=GB,serialNumber=xxx,OID.xxx=Private Organization,OID.xxxx=GB * start date: Mar 05 00:00:00 2011 GMT * expire date: Mar 04 23:59:59 2013 GMT * common name: live.sagepay.com * issuer: CN=VeriSign Class 3 Extended Validation SSL SGC CA,OU=Terms of use at https://www.verisign.com/rpa (c)06,OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US > POST /gateway/service/vspserver-register.vsp HTTP/1.1^M Host: live.sagepay.com^M Accept: */*^M Content-Length: 664^M Content-Type: application/x-www-form-urlencoded^M ^M < HTTP/1.1 200 OK^M < Date: Wed, 15 Jun 2011 16:11:43 GMT^M < Server: Microsoft-IIS/6.0^M < X-Powered-By: ASP.NET^M < Content-Language: en-GB^M < Content-Length: 276^M < Set-Cookie: NSC_wjq-tbhfqbz-dpn-ofx=xxxx;expires=Wed, 15-Jun-2011 16:48:26 GMT;path=/;secure;httponly^M < ^M * Connection #0 to host live.sagepay.com left intact 

Редактировать: проблема была в NSS, перекомпилирована завитка с OpenSSL и еще несколько обручей для зависимостей (libssh2), и пока она работает нормально.

Ура!

Solutions Collecting From Web of "PHP – зависание curl_exec"

добавьте в конце свой скрипт, чтобы получить причину сбоя

 if( $rawresponse === false ) syslog( LOG_INFO , "base.php::requestPost() : ".curl_error($curlSession) ); 

ИЗМЕНИТЬ 1

Это может быть внутренняя проблема завитка. Перед проверкой все время выполнения сервера обновляется (по крайней мере, php, php-curl и apache). Проверьте все их журналы ….. Затем я бы рекомендовал сравнивать результаты между несколькими производственными средами или средой dev / test.

Наконец, попробуйте сузить минимальный тестовый файл, который может воспроизвести вашу проблему и опубликовать полный код для тестового примера.

Трассировка стека ясно показывает, что разрыв произошел в криптографической библиотеке NSS, которую создала libcurl для использования в SSL.

У libcurl множество исправлений, связанных с NSS, с версии libcurl, которую вы используете, и, возможно, вы не используете самую последнюю версию NSS. Я настоятельно рекомендую вам рассмотреть возможность обновления до самого последнего и самого большого, прежде чем вы вытащите все свои волосы из этой проблемы.

Чтобы отладить эту проблему, я бы рекомендовал вам попробовать повторить ее с помощью командной строки curl с того же сервера и эффективно использовать команду -trace-ascii.

Проблема была NSS. Я перекомпилировал curl с OpenSSL и до сих пор не обнаружил никаких проблем.

Ура!

Вы пытались установить другую версию apache и php? Есть ли у вас в диспетчере пакетов? Если нет, попробуйте выполнить компиляцию последних apache, php и curl вручную и посмотреть, получите ли вы тот же результат.

NSS является более строгим, чем OpenSSL или GnuTLS. Корректор Fedora / RHEL по умолчанию использует NSS поверх OpenSSL и может ловить ошибки, которые не возникают при использовании curl на OSX, Ubuntu и т. Д.

Вот список кодов ошибок NSS http://www.mozilla.org/projects/security/pki/nss/ref/ssl/sslerr.html

 [root@mybox ~]# curl -k -v -E /etc/mycert.pem https://127.0.0.1/ * About to connect() to 127.0.0.1 port 443 (#0) * Trying 127.0.0.1... connected * Connected to 127.0.0.1 (127.0.0.1) port 443 (#0) * Initializing NSS with certpath: sql:/etc/pki/nssdb * warning: ignoring value of ssl.verifyhost * NSS error -8054 * Closing connection #0 * SSL connect error curl: (35) SSL connect error 

Если curl_exec зависает, это может быть из-за проблемы DNS или цикла перенаправления. Другими словами, в функции может быть ничего плохого, но с сетевым маршрутом вашего запроса. Может быть тупиком с циклом localhost. Ура!