公司中有不少服務是以curl或者soap方式連接第三方公司做的服務來交互數據,最近新增加了個需求,就是第三方服務發版時候,連接不上對方服務器時候要進行重試,其它原因導致的業務處理失敗,則按失敗處理,不會再進行調用。
思路就是判斷curl或者soap連接不上對方服務器時候,拋出TimeoutException異常,捕獲后做重試處理,其它錯誤導致的拋出的Exception則按失敗處理。
$ch = curl_init($url);
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 5, //5秒連接時間
CURLOPT_TIMEOUT => 30, //30秒請求等待時間
);
curl_setopt_array($ch, $options);
$response = curl_exec($ch);
if ($no = curl_errno($ch)) {
$error = curl_error($ch);
curl_close($ch);
//$no錯誤碼7為連接不上,28為連接上了但請求返回結果超時
if(in_array(intval($no), [7, 28], true)) {
throw new TimeoutException('連接或請求超時' . $error, $no);
}
}
curl_close($ch);
php文檔并沒詳細寫soap超時或者連接不上返回的具體代碼,業務處理失敗或者連接不上等所有不成功,都會拋出一個SoapFault異常,看了下php的源碼發現,還是有定義的
add_soap_fault(this_ptr, "HTTP", "Unable to parse URL", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", "Unknown protocol. Only http and https are allowed.", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", "SSL support is not available in this build", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", "Could not connect to host", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", "Failed Sending HTTP SOAP request", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", "Failed to create stream??", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", "Error Fetching http headers", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", "Error Fetching http body, No Content-Length, connection closed or chunked data", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", "Redirection limit reached, aborting", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", "Didn't receive an xml document", NULL, err);
add_soap_fault(this_ptr, "HTTP", "Unknown Content-Encoding", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", "Can't uncompress compressed response", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", http_msg, NULL, NULL);
ini_set('default_socket_timeout', 30); //定義響應超時為30秒
try {
$options = array(
'cache_wsdl' => 0,
'connection_timeout' => 5, //定義連接超時為5秒
);
libxml_disable_entity_loader(false);
$client = new \SoapClient($url, $options);
return $client->__soapCall($function_name, $arguments);
} catch (\SoapFault $e) {
//超時、連接不上
if($e->faultcode == 'HTTP'){
throw new TimeoutException('連接或請求超時', $e->getCode());
}
}