Zoom API 间歇性挂起问题求助及代码参考
Zoom API间歇性挂起导致脚本超时问题求助
我们开发了一款脚本,通过Zoom API从外部数据源同步联系人信息至Zoom通讯录,并将部分Contact Center数据存储至数据库供客服使用。整体运行正常,但遇到Zoom API间歇性挂起的问题:有时脚本运行顺畅,有时请求无法通过(已通过Zoom App日志确认)。按逻辑,脚本通过next_page_token分页查询,本该正常终止,但实际会持续等待直到服务器超时,似乎一直在等待Zoom API返回数据。
求问是否有人遇到过类似问题,或有潜在解决方法?
当前API调用函数
function getZoomApiData($method, $curl_url, $curl_password, array $post_data = array()) { $res_arr = $head_arr = $header_arr = array(); $response = $data = ""; $curl = curl_init(); switch($method) { case "POST": curl_setopt($curl, CURLOPT_POST, 1); if(!empty($post_data)) { //$data = flattenHttpArrayHelperZoom($post_data);/// does not work for some reason //$curl_url = sprintf("%s?%s", $curl_url, http_build_query($post_data)); curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($post_data)); } break; case "PATCH": curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PATCH'); if(!empty($post_data)) { //$data = flattenHttpArrayHelperZoom($post_data);/// does not work for some reason //$curl_url = sprintf("%s?%s", $curl_url, http_build_query($post_data)); curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($post_data)); } break; case "PUT": curl_setopt($curl, CURLOPT_PUT, 1); if(!empty($post_data)) { $curl_url = sprintf("%s?%s", $curl_url, http_build_query($post_data)); } break; case "DELETE": curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE"); if(!empty($post_data)) { $curl_url = sprintf("%s?%s", $curl_url, http_build_query($post_data)); } break; default: if(!empty($post_data)) { $curl_url = sprintf("%s?%s", $curl_url, http_build_query($post_data)); } } curl_setopt($curl, CURLOPT_URL, $curl_url); $authorization = "Authorization: Bearer " . $curl_password; if($method == "POST" || $method == "PATCH") { curl_setopt($curl, CURLOPT_HTTPHEADER, array($authorization, 'Content-Type: application/json')); }else { curl_setopt($curl, CURLOPT_HTTPHEADER, array($authorization, 'Content-Type: application/x-www-form-urlencoded')); } curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($curl, CURLOPT_VERBOSE, 1); curl_setopt($curl, CURLOPT_HEADER, 1); //// TESTING - OUTPUT REQUEST DATA //// // $request = curl_getinfo($curl); // echo "<pre>"; // print_r($request); // echo "</pre>"; /////////////////////////////////////// $response = curl_exec($curl); $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE); $headers = substr($response, 0, $header_size); $head_arr = explode(PHP_EOL, $headers); foreach($head_arr as $key => $value) { if($key === 0) { $header_arr['http_code'] = $head_arr[$key]; }else { $temp_arr = explode(': ', $head_arr[$key]); if(isset($temp_arr[0], $temp_arr[1])) { $header_arr[$temp_arr[0]] = $temp_arr[1]; } } } $response_body = substr($response, $header_size); $res_arr = json_decode($response_body, true); curl_close($curl); usleep(500 * 1000); return array("header_arr"=>$header_arr, "body_arr"=>$res_arr); }
API调用示例
function listAllQueueEngagements($access_token, $date_from, $date_to, $queue_id) { $output_arr = array(); $curl_url = "https://api.zoom.us/v2/contact_center/engagements"; $curl_method = "GET"; $next_page_token = ""; do { $post_data = array( "queue_id"=>$queue_id, "from"=>$date_from, "to"=>$date_to, "page_size"=>75, "next_page_token"=> $next_page_token ); $res_arr = getZoomApiData($curl_method, $curl_url, $access_token, $post_data); if(isset($res_arr['body_arr']['next_page_token'])) { $next_page_token = $res_arr['body_arr']['next_page_token']; }else { $next_page_token = ""; } if(isset($res_arr['body_arr']['engagements'])) { $output_arr = array_merge($output_arr, $res_arr['body_arr']['engagements']); } }while ($next_page_token !== ''); return $output_arr; }
潜在解决方法
1. 给CURL设置超时时间
当前代码未设置CURL超时参数,一旦API无响应,脚本会无限等待直到服务器超时。添加以下参数到getZoomApiData函数中:
// 设置连接超时(10秒) curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10); // 设置总请求超时(30秒) curl_setopt($curl, CURLOPT_TIMEOUT, 30);
2. 增加CURL错误处理
检查curl_exec返回值,请求失败时记录错误并终止循环,避免死等:
修改getZoomApiData中$response = curl_exec($curl);后的逻辑:
if($response === false) { $error = curl_error($curl); curl_close($curl); error_log("Zoom API请求失败: " . $error); return array("header_arr"=>[], "body_arr"=>[], "error"=>$error); }
同时在listAllQueueEngagements中处理错误:
$res_arr = getZoomApiData($curl_method, $curl_url, $access_token, $post_data); if(isset($res_arr['error'])) { error_log("获取队列数据失败: " . $res_arr['error']); $next_page_token = ""; continue; }
3. 优化分页逻辑,增加重试机制
针对间歇性失败,添加重试逻辑(调用方示例):
$max_retries = 3; $retry_count = 0; do { $res_arr = getZoomApiData($curl_method, $curl_url, $access_token, $post_data); if(isset($res_arr['error'])) { $retry_count++; if($retry_count >= $max_retries) { error_log("重试次数耗尽,终止请求"); $next_page_token = ""; break; } usleep(1000 * 1000); // 重试前延长等待时间 continue; } // 原有处理逻辑 if(isset($res_arr['body_arr']['next_page_token'])) { $next_page_token = $res_arr['body_arr']['next_page_token']; }else { $next_page_token = ""; } if(isset($res_arr['body_arr']['engagements'])) { $output_arr = array_merge($output_arr, $res_arr['body_arr']['engagements']); } } while ($next_page_token !== '');
4. 完善响应校验
当API响应无法解析为JSON时,终止循环:
在getZoomApiData中添加JSON解析校验:
$res_arr = json_decode($response_body, true); if(json_last_error() !== JSON_ERROR_NONE) { error_log("Zoom API响应解析失败: " . json_last_error_msg()); return array("header_arr"=>$header_arr, "body_arr"=>[], "error"=>"JSON解析失败"); }
5. 适配Zoom API速率限制
检查API返回的速率限制头信息,剩余请求不足时延长等待:
// 在getZoomApiData中添加 if(isset($header_arr['X-RateLimit-Remaining']) && $header_arr['X-RateLimit-Remaining'] < 5) { usleep(2000 * 1000); // 延长等待至2秒 }
内容的提问来源于stack exchange,提问作者Lukas Reeves
相关产品推荐
相关产品推荐

