使用Google API PHP客户端库

时间:2016-11-21 17:15:11

标签: php google-api google-api-php-client

我正在运行一个网络应用,以获取使用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 个答案:

答案 0 :(得分:1)

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

但是,根据您所做的事情,您实际上并不想在一般网络术语中实施exponential backoff procedure。你真的想要限制请求,所以你不要抨击API。根据您迭代的$pageToken的数量,您可以在执行下一次迭代之前执行sleep

此外,$pageToken = $results->getNextPageToken();在一次请求后会变成什么?因为你是从响应中设置它而不是以编程方式递减它,这可能会导致一个infinute循环或那种性质的东西。

答案 1 :(得分:0)

因此,经过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);

我现在已经尝试了这个解决方案两天了,它的工作就像一个魅力。希望这可能对其他人有帮助。我现在很高兴。 :)