代码之家  ›  专栏  ›  技术社区  ›  Morfinismo

使用Google API PHP客户端库的指数回退

  •  1
  • Morfinismo  · 技术社区  · 8 年前

    我正在运行一个web应用程序,使用Google API PHP客户端库2.0.3获取用户列表,并将其保存到CSV文件,同时,我正在跟踪屏幕上的进程。我使用的代码如下:

    $pageToken = null;
    $optParams = array(
        "customer" => "my_customer",
        "maxResults" => 500,
        "orderBy" => "email",
        "sortOrder" => "ASCENDING"
    );
    
    try {
    
        $usernum = 0;
    
        do {
    
            if ($pageToken){
                $optParams['pageToken'] = $pageToken;   
            }           
    
            $results = $service->users->listUsers($optParams);
            $pageToken = $results->getNextPageToken();
            $users = $results->getUsers();
    
            foreach ($users as $user) {
    
                $usernum++; 
    
                $csvfileusers = array($user->getPrimaryEmail());
                fputcsv($savecsv, $csvfileusers);
    
                $usersemails = $user->getPrimaryEmail();
                print "<li>".$usernum." - <font color='#9dd7fb'>".$usersemails."</font></li>";
    
            }
    
        } while($pageToken); 
    
    } catch (Exception $e) {
    
        print "An error occurred: " . $e->getMessage();
    
    }
    

    一切正常。问题是,我时不时地 { error: { errors: [ { domain: global, reason: backendError, message: Service unavailable. Please try again } ], code: 503, message: Service unavailable. Please try again } }

    我知道这意味着我向Google服务器发送请求的速度太快,因此我需要实现指数回退解决方案。我的问题是我不知道怎么做。是否有人能提供一个如何使用PHP客户端库的示例?我知道,从长远来看,我可能能够解决这个问题,但如果我能得到一些帮助,我将非常感激。

    2 回复  |  直到 8 年前
        1
  •  2
  •   kyle    8 年前

    不幸的是,文档是 lacking for the actual backoff implementation 然而,Google_Task_Runner类概述了退避实现过程。 You can see how it does it here .

    然而,基于您正在做的,您实际上不想实现 exponential backoff procedure 在一般网络术语中。你真的想限制请求,这样你就不会猛击API了。取决于多少 $pageToken 你在迭代,你可以做一个 sleep 在进行下一次while迭代之前。

    此外,它做什么 $pageToken = $results->getNextPageToken();

        2
  •  2
  •   Morfinismo    6 年前

    因此,经过20天的尝试和调查,感谢@kyle提供的信息,我想出了这个指数退避解决方案。

    $attemptNum = 1; // retry attempt
    $expBackoff = false; // exponential backoff rety indicator
    
    do {
    
        if($attemptNum <= 4) {
            try {
    
                $usernum = 1;
    
                do {
    
                    if ($pageToken){
                        $optParams['pageToken'] = $pageToken;   
                    }           
    
                    $results = $service->users->listUsers($optParams);
                    $pageToken = $results->getNextPageToken();
                    $users = $results->getUsers();
    
                    foreach ($users as $user) {
    
                        $csvfileusers = array($user->getPrimaryEmail());
                        fputcsv($savecsv, $csvfileusers);
    
                        $usersemails = $user->getPrimaryEmail();
                        print "<li>".$usernum." - <font color='#9dd7fb'>".$usersemails."</font></li>";
                        $usernum++; 
    
                    }
    
                } while($pageToken); 
    
            } catch (Exception $e) {
    
                $err503ReasonA = "Service unavailable"; // Service unavailable.
                $err503ReasonB = "Backend Error"; //Backend Error
    
                $exception = $e->getMessage();
    
                if(strpos($exception, $err503Reason) !== false || strpos($exception, $err503ReasonB) !== false){    
                    $expBackoff = true;
                    $sleeptime = $retrynum * 1; //retrynum * seconds
                    sleep($sleeptime);
                    $retrynum++;
                } else {
                    $expBackoff = false;
                    print "There was an error -> $exception";
                }
            }
    
        } else {
            $expBackoff = false;
        }
    
    } while ($expBackoff);
    

    我已经尝试这个解决方案两天了,效果很好。希望这对其他人有帮助。我现在很高兴