Aperçu
Zencoder est une dépendance logicielle essentielle pour la plupart de nos clients. Et même si nous visons une disponibilité de 100 %, il peut arriver que vous ne puissiez pas vous connecter à Zencoder :
Lorsque cela se produit et que Zencoder est en panne, votre application recevra généralement une réponse `` 503 Service indisponible '' de Zencoder, mais vous pourriez obtenir une erreur différente (comme un 500). Si vous avez dépassé votre limite de débit API, vous obtiendrez une réponse «Limite de débit 403 dépassée».
Bonne nouvelle : puisque l'encodage vidéo est un processus asynchrone, vous pouvez créer votre application pour ne jamais rencontrer de temps d'arrêt ou de problèmes liés à notre disponibilité. Si vous faites cela, le pire des cas est que vos travaux prennent un peu plus de temps. Mais aucune erreur ne se produit. Nous vous recommandons vivement de le faire.
Pour le dire plus clairement, si vous vous souciez de la fiabilité, vous devez suivre cette approche d'intégration - pour Zencoder ou pour toute API critique avec laquelle vous vous intégrez.
- Notre service peut être affecté par des problèmes chez un fournisseur en amont (par exemple, Amazon Web Services)
- Nous devons parfois effectuer une maintenance du système qui nécessite des temps d'arrêt temporaires
- Vous avez dépassé votre Limite de débit API
- etc.
Intégration fiable des applications
- Inclure un URL secondaire comme sauvegarde en cas d'échec du téléchargement vers votre emplacement principal.
- Si vous obtenez un code de réponse non réussi de Zencoder - en gros, autre chose qu'un 200 ou 201 - n'échouez pas le travail. Un code de réponse de 503 ne signifie pas que votre vidéo ne peut pas être traitée. Cela signifie simplement que Zencoder est temporairement indisponible.
- Si vous obtenez un erreur de connexion lorsque vous essayez de vous connecter à Zencoder, faites la même chose.
- De même, encapsulez vos requêtes API dans un délai d'expiration. Nous recommandons un délai d'attente de 30 secondes ; Zencoder répond généralement en moins d'une seconde, donc 30 secondes sont généralement suffisantes.
- Dans ces trois cas, si vous obtenez un code de réponse non réussi, si vous ne parvenez pas à vous connecter ou si la demande d'API est en attente, signalez la tâche comme étant « en attente ».
- Périodiquement, soumettez à nouveau tous les travaux dans l'état «en attente». Vous pouvez utiliser cron pour faire cela toutes les minutes, par exemple.
Une fois que les travaux sont soumis à nouveau, tout se comporte normalement. De cette façon, une soumission de travail échouée ne fait que prendre un peu plus de temps que de causer des problèmes à votre application ou à vos utilisateurs.
Pseudocode
OK, donc ce n'est pas un pseudocode, c'est Ruby. Mais Ruby est assez facile à lire.
- Imaginez un tableau Vidéos qui inclut ces colonnes. (Il en aura évidemment plus, y compris des colonnes pour stocker un ID de travail Zencoder et un ID de fichier de sortie Zencoder.)
create_table :videos do |t| t.string :state t.integer :lock_version t.index :state end
- Une vidéo doit inclure une machine à états présentant les états suivants :
- en attente (pas encore soumis à Zencoder)
- soumission (en cours de soumission à Zencoder)
- transcodage (soumis avec succès à Zencoder)
- terminé (Zencoder a terminé le transcodage et le travail est terminé)
- a échoué (Zencoder n'a pas pu transcoder la vidéo)
- Lorsqu'une nouvelle vidéo est ingérée, enregistrez la vidéo dans l'état «soumission» et déclenchez une tâche d'arrière-plan pour soumettre la vidéo à Zencoder.
# got a new video! video = Video.new(params) video.state = "submitting" video.save! submit_to_zencoder(video)
Vous devriez vraiment utiliser la méthode submit_to_zencoder en arrière-plan. Dans Ruby, en utilisant DelayedJob, cela peut ressembler à ceci :
delay.submit_to_zencoder(video)
Mais nous allons rester avec notre
submit_to_zencoder(video)
méthode à des fins d'exemple. - La
submit_to_zencoder
fonction ressemble à ceci. Cela doit être exécuté de manière asynchrone, en arrière-plan.def submit_to_zencoder(video) begin response = Zencoder::Job.create(attributes, :timeout => 30_000) if response.code == 201 video.state = "transcoding" else video.state = "pending" end video.save! # Rescue any connection error. Our plugin abstracts these as # Zencoder::HTTPError. # # If you're not using the Zencoder plugin, this includes things # like Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::ECONNREFUSED, # Errno::EHOSTDOWN, and SocketError. rescue Timeout::Error, Zencoder::HTTPError video.state = "pending" video.save! end end
- De temps en temps, par exemple toutes les minutes, essayez de resoumettre les travaux qui sont dans l'état «en attente».
def resubmit_pending_jobs Video.where(:state => "pending").find_each do |video| begin video.state = "submitting" video.save! submit_to_zencoder(video) rescue ActiveRecord::StaleObjectError end end end
De plus, en ajoutant une colonne 'lock_version' à la table videos, nous introduisons un verrouillage optimiste. Cela signifie que si l'enregistrement est mis à jour entre la
Video.find
requête etvideo.save
, il ne soumettra pas la tâche à Zencoder. Cela empêchera le travail d'être soumis à Zencoder deux fois par accident. Vous pouvez utiliser le verrouillage pessimiste ou de base de données ou une autre méthode de verrouillage pour accomplir la même chose.C'est si facile…
Tout bien considéré, il s'agit d'une approche assez simple pour assurer une fiabilité d'intégration à 100% entre Zencoder et votre application. Il s'agit de quelques étapes supplémentaires que de simplement soumettre naïvement une tâche, mais cela garantit que peu importe ce qui se passe - qu'il s'agisse d'un délai d'expiration occasionnel, d'un temps d'arrêt inattendu chez Zencoder ou de maintenance planifiée, votre application fonctionne de manière fiable.