English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
【Acesso HTTP】
Nós temos muitos métodos para acessar HTTP, principalmente: curl, socket, file_get_contents() e outros.
Se a outra parte do servidor não responder, ficamos em uma situação trágica, é fácil matar todo o servidor, então também precisamos considerar o problema de timeout ao acessar HTTP.
[Acesso HTTP via CURL]
CURL é uma biblioteca de lib que usamos frequentemente para acessar interfaces de protocolo HTTP, confiável, com alto desempenho e algumas funções de suporte a concorrência.
CURL:
curl_setopt($ch, opt) pode configurar algumas configurações de tempo limite, incluindo principalmente:
*(Importante) CURLOPT_TIMEOUT define o número máximo de segundos permitido para a execução do cURL.
*(Importante) CURLOPT_TIMEOUT_MS define o número máximo de milissegundos permitido para a execução do cURL. (No cURL 7.16.2foi adicionado. A partir do PHP 5.2.3Disponível a partir de agora. )
CURLOPT_CONNECTTIMEOUT é o tempo de espera antes de estabelecer a conexão, se definido como 0, espera infinitamente.
CURLOPT_CONNECTTIMEOUT_MS é o tempo de espera para tentar conectar, em milissegundos. Se definido como 0, espera infinitamente. No cURL 7.16.2foi adicionado. A partir do PHP 5.2.3Disponível a partir de agora.
CURLOPT_DNS_CACHE_TIMEOUT configura o tempo de armazenamento de informações de DNS na memória, o valor padrão é120 segundos.
Tempo limite normal em segundos para curl:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60); //Basta configurar um número de segundos
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_USERAGENT, $defined_vars['HTTP_USER_AGENT']);
Uso de tempo limite normal em segundos para curl:
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
Para que o curl possa usar tempo limite em milissegundos, é necessário adicionar:
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
ou:
curl_setopt ($ch, CURLOPT_NOSIGNAL, true); é compatível com configuração de tempo limite em milissegundos
Exemplo de tempo limite de milissegundos para curl:
<?php if (!isset($_GET['foo'])) { // Client $ch = curl_init('http://example.com/'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_NOSIGNAL, 1); //Atenção, o tempo limite em milissegundos deve ser configurado curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200); //milissegundos de timeout, cURL 7.16.2foi adicionado. A partir do PHP 5.2.3Pode usar $data = curl_exec($ch); $curl_errno = curl_errno($ch); $curl_error = curl_error($ch); curl_close($ch); if ($curl_errno > 0) { echo "Erro do cURL ($curl_errno): $curl_error\n"; } else { echo "Dado recebido: $data\n"; } } else { // Servidor sleep(10); echo "Concluído."; } ?>
Outras dicas:
1. Segundo a experiência, é: cURL versão >= libcurl/7.21.0 versão, o timeout de milissegundos é definitivamente eficaz, lembre-se disso.
2. O timeout de milissegundos do curl_multi também tem problemas ... A única chamada suporta timeout de milissegundos, curl_multi não é preciso para várias chamadas paralelas
[Acesso ao HTTP por meio de tratamento de fluxo]
Além do curl, também usamos frequentemente fsockopen, ou funções de operação de arquivo para lidar com o protocolo HTTP, então, o tratamento de timeout nessa área também é necessário.
O timeout de conexão pode ser configurado diretamente, mas o timeout de leitura de fluxo precisa ser tratado separadamente.
Escreva seu código para lidar:
$intUSGone = ($tmCurrent['sec'] - $tmStart['sec']) * 10 + ($tmCurrent['usec'] - $tmStart['usec']); if ($intUSGone > $this->_intReadTimeoutUS) { return false; }
ou use as funções de manipulação de fluxo integradas stream_set_timeout() e stream_get_meta_data() para lidar com:
<?php // Timeout em segundos $timeout = 5; $fp = fsockopen("example.com", 80, $errno, $errstr, $timeout); if ($fp) { fwrite($fp, "GET"); / HTTP/1.0\r\n"); fwrite($fp, "Host: example.com\r\n"); fwrite($fp, "Conexão: Fechar\r\n\r\n"); stream_set_blocking($fp, true); //Important, set to non-blocking mode stream_set_timeout($fp,$timeout); //Set timeout $info = stream_get_meta_data($fp); while ((!feof($fp)) && (!$info['timed_out'])) { $data .= fgets($fp, 4096); $info = stream_get_meta_data($fp); ob_flush; flush(); } if ($info['timed_out']) { echo "Connection Timed Out!"; } else { echo $data; } }
file_get_contents timeout:
<?php $timeout = array( 'http' => array( 'timeout' => 5 //Set a timeout, unit is seconds ) ); $ctx = stream_context_create($timeout); $text = file_get_contents("http://example.com/", 0, $ctx); ?>
fopen timeout:
<?php $timeout = array( 'http' => array( 'timeout' => 5 //Set a timeout, unit is seconds ) ); $ctx = stream_context_create($timeout); if ($fp = fopen("http://example.com/", "r", false, $ctx)) { while( $c = fread($fp, 8192)) { echo $c; } fclose($fp); } ?>
This is the full content of the brief discussion on solving the timeout problem of the backend and interface access after PHP processing brought to you by the editor. I hope everyone will support and cheer for the tutorial ~