在微服务架构中, 多API请求往往占据很长时间, 特别是对于那些没有相互依赖的api请求, 我们可以调整为并发请求,如此能大大节约api请求总时间。
下面的函数是利用curl并发请求改写的一个函数, 可以很好的解决多api请求的问题。
function multi_curl($requests = [])
{
$response = [];
$hander = [];
$mh = curl_multi_init();
foreach($requests as $id=>$item) {
if(empty($item['url'])) {
throw new \Exception('基本参数URL不能为空');
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $item['url']);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect: '));
if(defined('CURLOPT_IPRESOLVE') && defined('CURL_IPRESOLVE_V4')){
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
}
curl_setopt($ch, CURLOPT_TIMEOUT, isset($item['timeout']) ? $item['timeout'] : 3);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, isset($item['method']) ? $item['method'] : 'GET');
//设置请求参数
if(isset($item['data'])) {
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($item['data']));
}
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
//定义api请求认证信息
if(defined('API_USERNAME') && defined('API_PASSWORD')) {
curl_setopt($ch, CURLOPT_USERPWD, API_USERNAME . ":" . API_PASSWORD);
}
curl_multi_add_handle($mh,$ch);
$hander[$id] = $ch;
}
$running=null;
do {
usleep(1000);
curl_multi_exec($mh,$running);
} while ($running > 0);
//get content and remote handle
foreach($hander as $id=>$ch) {
$response[$id] = curl_multi_getcontent($ch);
//检查结果是否需要转换为json, 默认转换
$toArray = isset($requests[$id]['to_array']) ? $requests[$id]['to_array'] == true : true;
if($toArray) {
//$response[$id] = json_decode(trim($data, chr(239) . chr(187) . chr(191)), true);
$response[$id] = json_decode($response[$id], true);
}
curl_multi_remove_handle($mh, $ch);
}
curl_multi_close($mh);
//检查是否进行数组转换, 默认转换为数组
return $response;
}