0

Nous disposons d'un éditeur vidéo basé sur mobile qui télécharge les vidéos et les miniatures des utilisateurs dans un compartiment AWS S3. Cela lance ensuite un processus AWS SWF pour encoder, télécharger la vidéo, télécharger la vignette et attendre le traitement de la vidéo avant de dire à l'utilisateur que sa vidéo est terminée. Chaque utilisateur utilise ses propres jetons d'accès pour que les vidéos soient téléchargées sur ses propres chaînes YouTube. Cela a bien fonctionné au cours des 12 derniers mois, en lançant occasionnellement backendError sur le téléchargement de vignettes à partir de la fin YouTube, que nous avons une stratégie de réessai qui attendra 1, 3, 8, 15 etc, secondes. À la deuxième ou troisième tentative, les serveurs YouTube se sont triés et tout est de nouveau génial.La définition d'une vignette via l'API provoque 503 backendError

En date du 2017-09-17 17:29 (AEST) aucune de nos vidéos n'a réussi à télécharger sa vignette. Système jette un Google_Service_Exception avec le code d'état de 503 et le corps de réponse,

{ "erreur": { "erreurs": [{ "domaine": "global", "raison": "backendError", "message": "erreur backend"}], "code": 503, "message": "erreur backend"}}

A cette époque, aucun paquet de serveur ont été mis à jour, ni était l'un de nos propres code ou des paquets compositeurs utilisés. J'ai essayé de révoquer mon jeton d'accès, j'ai généré mon propre projet et une nouvelle clé/secret d'API sur un compte différent et j'ai toujours la même erreur de traitement de la vignette sur notre serveur de test (devrait exclure la limitation de débit loin en dessous de toutes les restrictions).

Le téléchargement vidéo fonctionne toujours correctement. La modification du titre vidéo de notre système fonctionne toujours correctement (cela signifie que le jeton d'accès est fonctionnel et qu'il a les étendues requises pour définir une vignette si le canal le permet). Le téléchargement manuel d'une vignette directement sur YouTube fonctionne toujours correctement (cela exclut le fait que la chaîne ait elle-même un problème).

J'ai même re-téléchargé le sample code et créé un nouveau test et il échoue toujours. La ligne spécifique, il échoue à dans tous les cas est

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

Je ne sais pas ce qui pourrait être la cause de ce problème soudain si rien changé sur notre fin, toutes les images sont 1920x1080 jpgs bien sous 2MB, projet complètement différent et jetons accès , complètement nouvel exemple de code. Et je suppose que si tout le monde utilisant l'API de données YouTube a eu cette erreur au cours des dernières 24 heures, il y aurait beaucoup plus de messages à ce sujet. Donc je ne sais pas quoi d'autre à essayer de notre côté.

Des suggestions?

EDIT: Eh bien ... c'est bizarre. J'ai réussi à télécharger via la ligne de commande de notre serveur avec cURL.

curl -X POST -F "[email protected]_test.jpg" "https://www.googleapis.com/upload/youtube/v3/thumbnails/set?videoId=dCdQ2tJ5wIs&key={REMOVED}&access_token={REMOVED}" 

Et cela a bien fonctionné. Donc, cela exclut le problème avec notre serveur (IP bloqué ou quelque chose), problème avec nos jetons d'accès ou problème avec notre clé client_id. Il exclut aussi en quelque sorte le backend de YouTube qui se comporte mal (en supposant que cURL et php se connectent via les mêmes mécanismes). Cela me laisse seulement avec, notre téléchargement de vignettes sur YouTube (et seulement les vignettes) échoue maintenant de PHP sans changement de serveur ou de code serveur, mais en utilisant des jetons d'accès et des clés identiques via cURL dans la ligne de commande fonctionne très bien.

EDIT 2: J'ai téléchargé un échantillon here on github (inclut un exemple de fichier image et composer.json). Il a 2 échantillons dans 1. Affiche le script échouant avec youtube php sdk, mais travaillant ensuite correctement avec une requête curl utilisant les mêmes informations d'identification. Le script n'inclut pas l'obtention d'un jeton d'accès ou d'actualisation.

Le script test.php principal est le suivant.

<?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: $filesize\n"; 
    $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 success\n";        
} 
catch (Google_Service_Exception $err) 
{ 
    echo $err->getMessage(); 
} 
catch (Exception $err) 
{ 
    echo $err->getMessage(); 
} 
+0

Les questions qui demandent une aide au débogage («pourquoi ce code ne fonctionne-t-il pas?») Doivent inclure le comportement souhaité, un problème ou une erreur spécifique et le code le plus court nécessaire pour le reproduire dans la question. Les questions sans énoncé de problème clair ne sont pas utiles aux autres lecteurs. Voir: Comment créer un exemple minimal, complet et vérifiable. – DaImTo

+0

Pouvez-vous créer un lien vers l'exemple minimal, complet et vérifiable pour moi afin que je puisse mettre à jour la question avec les meilleures pratiques pour les autres lecteurs? –

+1

https://stackoverflow.com/help/mcve Vous ne devez pas inclure votre ID client et le secret que j'ai le mien. – DaImTo

Répondre

0
{ 
    "error":{ 
     "errors":[ 
     { 
      "domain":"global", 
      "reason":"backendError", 
      "message":"Backend Error" 
     } 
     ], 
     "code":503, 
     "message":"Backend Error" 
    } 
} 

une erreur de serveur sur le côté Googles. Il n'y a rien que vous pouvez vraiment faire en dehors d'attendre quelques minutes et essayez à nouveau. Il est normalement causé par aller au jeûne. Action suggérée: Utiliser exponential backoff, inclure une vérification avant de réessayer des requêtes non-idempotentes.

La mise en œuvre exponentielle backoff

est backoff Exponentielle une stratégie de gestion des erreurs standard pour les applications de réseau dans lequel le client réessaye périodiquement une demande ayant échoué sur une augmentation du temps. Si un volume élevé de requêtes ou un trafic réseau important oblige le serveur à renvoyer des erreurs, la suppression exponentielle peut être une bonne stratégie pour gérer ces erreurs. Inversement, il ne s'agit pas d'une stratégie pertinente pour traiter des erreurs sans rapport avec la limitation du débit, le volume réseau ou les temps de réponse, tels que les informations d'identification d'autorisation non valides ou les erreurs de fichier non trouvées.

Utilisée correctement, la fonction de repli exponentiel augmente l'efficacité de l'utilisation de la bande passante, réduit le nombre de requêtes requises pour obtenir une réponse satisfaisante et optimise le débit des demandes dans les environnements simultanés.

Les demandes de création ne sont pas idempotentes. Une nouvelle tentative est insuffisante et peut entraîner des doublons. Vérifiez si l'entité existe avant de réessayer.

Le flux pour la mise en œuvre d'une interruption exponentielle simple est le suivant.

  1. Faire une demande à l'API
  2. Recevez une réponse d'erreur qui a un code d'erreur Retry-mesure
  3. Wait 1s + random_number_milliseconds secondes
  4. demande Retry
  5. Recevoir une réponse d'erreur qui a retry-mesure code d'erreur
  6. attente 2s + random_number_milliseconds secondes
  7. demande de Retry
  8. Recevoir une réponse d'erreur qui a un code d'erreur retry-mesure
  9. attente 4s + random_number_milliseconds secondes
  10. Retry demande
  11. Recevoir une réponse d'erreur qui a un code d'erreur retry-mesure
  12. attente 8s + random_number_milliseconds secondes
  13. Retry demande
  14. Recevoir une réponse d'erreur qui a un code d'erreur retry-mesure
  15. attente 16s + random_number_milliseconds seconde
  16. Demande de nouvelle tentative
  17. Si une erreur persiste, arrêtez et notez l'erreur.
+0

Je pense que vous n'avez pas vraiment lu ma question. Nous avons mis en place une solution exponentielle. Le système a échoué pendant 24 heures. La requête CLI curl avec le même jeton d'accès, même clé, même vidéo youtube, même vignette, fonctionne 100% du temps, mais l'utilisation de php sdk échoue 100% du temps. Les deux de la même machine. –

+0

J'ai lu votre question et il n'y a pas d'autre solution pour ce problème. C'est une erreur de retour ou un problème de protection contre les inondations. Si vous avez correctement implémenté expiation exponentielle alors il n'y a rien d'autre que vous pouvez faire. Si cela fonctionne avec curl mais pas avec PHP alors avez-vous considéré que vous avez une boucle dans votre code quelque part qui spammerait l'API causant PHP de toujours retourner une erreur de protection contre les inondations? Comme vous n'avez pas assez de code pour recréer le problème, nous pouvons faire beaucoup. – DaImTo

+0

Exponentiel backoff n'a pas laissé les vignettes télécharger, nous avons enregistré l'erreur et c'est pourquoi nous sommes arrivés à SO après plus de 24 heures d'échec;) CLI fonctionne bien, via php échoue. L'environnement n'a pas été changé depuis environ une semaine. –

0

Et juste hors de nulle part, 4 jours plus tard, il se répare soudainement. Était un problème dans YT, mais pas un qui serait réplicable à travers tous leurs SDK pour une raison quelconque (comme, encore une fois, le serveur n'a pas été touché, le code à distance fonctionne soudainement, le code de test utilisé fonctionne soudainement).