通过API设置缩略图会导致503 BackendError



我们有一个基于移动设备的视频编辑器,该编辑器将人们的视频和缩略图上传到AWS S3存储桶中。然后,这将启动一个AWS SWF流程来编码,上传视频,上传缩略图并等待该视频处理,然后告诉用户他们的视频完成。每个用户都使用自己的访问令牌,以便将视频上传到自己的YouTube频道。

在过去的12个月左右的时间里,这很好,偶尔从YouTube End上传的缩略图上偶尔将后端部门扔出,我们有一个重试策略,该策略将等待1、3、8、15等。在第二或第三个重试时,YouTube服务器已经整理好了,一切都很棒。

截至2017-09-17 17:29(Aest)我们的视频都没有设法上传缩略图。系统将Google_service_exception带有503的状态代码,

的响应主体

{" error":{" errors":[{{ "域":"全球", "原因":" backenderror", "消息":"后端错误"}],"代码":503,"消息":"后端错误"}}

目前,没有更新服务器软件包,我们自己的任何代码也不是任何使用的作曲家软件包。

我尝试撤销我的访问令牌,在另一个帐户上生成了自己的新项目和新的API密钥/秘密,并且仍然在我们的测试服务器上获得相同的错误处理缩略图(应该排除速率限制,我们已经很远了低于任何限制)。

视频上传仍然可以正常工作。从我们的系统编辑视频标题仍然可以正常工作(意味着访问令牌功能是功能性的,并且需要示波器t设置缩略图,如果频道允许)。直接将缩略图上传到YouTube仍然可以正常工作(排除频道本身有问题)。

我什至重新下载了示例代码并创建了一个新测试,但它仍然失败。在所有情况下,它失败的特定行是

$status = $media->nextChunk($chunk);

我不知道,如果我们目前什么都没有改变,所有图像均为1920x1080 jpg在2MB下,完全不同的项目和访问令牌,全新的示例代码。而且我假设,如果每个使用YouTube数据API的人在过去24小时内都有此错误,那么它将有更多的帖子。因此,不确定还要从我们的尽头尝试什么。

有什么建议?

编辑:好吧...这很奇怪。我设法通过卷发从服务器上的命令行上传。

curl -X POST -F "image=@thumbnail_test.jpg" "https://www.googleapis.com/upload/youtube/v3/thumbnails/set?videoId=dCdQ2tJ5wIs&key={REMOVED}&access_token={REMOVED}"

这很好。因此,排除我们的服务器问题(IP阻止或其他内容),对我们的访问令牌发出发行或向客户端键发行。它还以某种方式排除了YouTube后端的表现不佳(假设Curl和PHP通过相同的机制连接)。

只留下我的,我们将缩略图上传到YouTube(和只有缩略图)现在因没有服务器或服务器代码更改而失败,但使用命令行中的curl使用相同的访问令牌和键,可以很好地工作。p>编辑2:我已经在GitHub上上传了一个示例(包括示例图像和Composer.json文件)。它在1中有2个样本。显示YouTube PHP SDK失败的脚本,但随后使用相同的凭据成功地使用Curl请求进行了工作。脚本不包括获取访问或刷新令牌。

主test.php脚本如下。

<?php 
define('GOOGLE_CLIENT_ID', 'REPLACE_ME');
define('GOOGLE_CLIENT_SECRET', 'REPLACE_ME');
require_once 'vendor/autoload.php';
$token = [
    'access_token' => 'REPLACE_ME',
    'refresh_token' => 'REPLACE_ME',
    'token_type' => 'Bearer',
    'expires_in' => '3600',
    'created' => REPLACE_ME
];
$youtube_id = 'REPLACE_ME';
$thumbnail_path = realpath('thumbnail.jpg');

/*
// Doing the exact same request in cURL works fine.
$data = [
    'filedata' => new CURLFile($thumbnail_path, 'image/jpeg', basename($thumbnail_path)),
];      
// Execute remote upload
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer '.$token['access_token'],
]);
curl_setopt($curl, CURLOPT_URL, 'https://www.googleapis.com/upload/youtube/v3/thumbnails/set?videoId='.$youtube_id.'&key='.GOOGLE_CLIENT_SECRET);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_VERBOSE, 1);
$response = curl_exec($curl);
curl_close($curl);
echo $response;
*/

// Based on php sample from https://developers.google.com/youtube/v3/docs/thumbnails/set
$client = new Google_Client();   
$client->setClientId(GOOGLE_CLIENT_ID);
$client->setClientSecret(GOOGLE_CLIENT_SECRET);
$client->setScopes([
    'https://www.googleapis.com/auth/yt-analytics.readonly', 
    'https://www.googleapis.com/auth/youtube', 
    'https://www.googleapis.com/auth/youtube.upload',
    'https://www.googleapis.com/auth/userinfo.email',
    'https://www.googleapis.com/auth/userinfo.profile',
]);
$client->setAccessType('offline');  
// If you want to use a refresh token instead to get an access token from it.
//$token = $client->fetchAccessTokenWithRefreshToken($refresh_token);
//var_dump($token);
$client->setAccessToken($token);
$service = new Google_Service_YouTube($client);
try
{
    // Specify the size of each chunk of data, in bytes. Set a higher value for
    // reliable connection as fewer chunks lead to faster uploads. Set a lower
    // value for better recovery on less reliable connections.
    $chunkSizeBytes = 1 * 1024 * 1024;
    // Create a MediaFileUpload object for resumable uploads.
    // Parameters to MediaFileUpload are:
    // client, request, mimeType, data, resumable, chunksize.
    $client->setDefer(true);
    $request = $service->thumbnails->set($youtube_id);
    $client->setDefer(false);
    $mimeType = 'image/jpeg';
    $media = new Google_Http_MediaFileUpload(
        $client,
        $request,
        $mimeType,
        null,
        true,
        $chunkSizeBytes
    );
    $filesize = filesize($thumbnail_path);
    echo "Filesize: $filesizen";
    $media->setFileSize($filesize);
    // Read the media file and upload it chunk by chunk.
    $status = false;
    $handle = fopen($thumbnail_path, "rb");
    while (!$status && !feof($handle))
    {
        $chunk = fread($handle, $chunkSizeBytes);
        $status = $media->nextChunk($chunk); // The line where the Google_Service_Exception exception is thrown. 
    }
    fclose($handle);
    echo "Thumbnail uploaded successn";                              
}
catch (Google_Service_Exception $err)
{
    echo $err->getMessage();
}
catch (Exception $err)
{
    echo $err->getMessage();
}
{  
   "error":{  
      "errors":[  
         {  
            "domain":"global",
            "reason":"backendError",
            "message":"Backend Error"
         }
      ],
      "code":503,
      "message":"Backend Error"
   }
}

是Google端的服务器错误。除了等待几分钟,再试一次。通常是由于快速而引起的。

建议的操作:使用指数向后,在重试非数字请求之前包括一张支票。

实施指数退回

指数退回是针对网络应用程序的标准错误处理策略,在该应用程序中,客户会在越来越多的时间内定期检索失败的请求。如果大量的请求或繁重的网络流量导致服务器返回错误,则指数向后可能是处理这些错误的好策略。相反,这不是处理与限制费率,网络量或响应时间无关的错误的相关策略,例如无效的授权凭证或未发现错误的文件。

使用正确使用,指数向后提高了带宽使用的效率,减少了获得成功响应所需的请求数,并最大程度地提高了并发环境中请求的吞吐量。

创建请求不是愿意的。简单的重试是不够的,可能会导致重复的实体。在重试之前检查该实体是否存在。

实现简单指数退回的流量如下。

  1. 请求API
  2. 收到具有重试错误代码的错误响应
  3. 等待1S Random_number_milliseconds秒
  4. 重试请求
  5. 收到具有重试错误代码的错误响应
  6. 等待2S Random_number_milliseconds秒
  7. 重试请求
  8. 收到具有重试错误代码的错误响应
  9. 等待4S Random_number_milliseconds秒
  10. 重试请求
  11. 收到具有重试错误代码的错误响应
  12. 等待8s andur_number_milliseconds秒
  13. 重试请求
  14. 收到具有重试错误代码的错误响应
  15. 等待16S RONARAM_NUMBER_MILLISECONDS秒
  16. 重试请求
  17. 如果您仍然有错误,请停止并记录错误。

,而只是在不在的地方,4天后,它突然固定自身。是YT中的一个问题,但由于某种原因,无法在其所有SDK上复制的问题(例如,服务器没有触摸,远程代码突然起作用,在本地使用的测试代码突然使用)。

相关内容

  • 没有找到相关文章

最新更新