Le backend de SoundCloud reposait sur des microservices dotés d'interfaces REST/JSON construites à la main, faciles à déboguer mais laissant les conventions de chaque point de terminaison à l'équipe qui l'avait bâti — méthode HTTP, noms de champs JSON, formats d'horodatage, formes des erreurs. Les directives internes n'aidaient que jusqu'à un certain point : un client avait un jour envoyé des champs en camelCase à un serveur qui attendait du snake_case et provoqué une panne, et comprendre un point de terminaison quelconque exigeait de lire le code applicatif plutôt qu'un contrat.

SoundCloud a construit Twinagle, une implémentation en Scala/Finagle du protocole RPC Twirp de Twitch, afin que les ingénieurs puissent définir une API une seule fois en protobuf et générer à partir de là le code serveur et client. Ils ont d'abord migré leur service d'autorisation de pistes à fort trafic. Plutôt que de basculer directement, ils ont fait tourner REST et Twirp côte à côte derrière un drapeau basé sur un pourcentage : aux faibles pourcentages de déploiement, les deux points de terminaison étaient appelés et comparés, seule la réponse REST étant renvoyée, de sorte que les divergences apparaissaient comme des écarts journalisés, et non comme des bugs visibles par les utilisateurs.

Mettre le trafic en miroir vers le nouveau point de terminaison, comparer les réponses, puis basculer

Générer le code serveur et client à partir d'un seul contrat protobuf a éliminé la catégorie de bugs causés par des équipes inventant leurs propres conventions de nommage de champs JSON et de HTTP.

Faire tourner les deux points de terminaison en parallèle sur un faible pourcentage de trafic avant de basculer a permis à l'équipe de détecter les divergences de réponses sans qu'aucun utilisateur ne voie une réponse erronée.

Commencer par un service à fort trafic et à client unique a maintenu la surface d'intégration de la première migration réduite tout en prouvant Twinagle sous charge réelle.

Laisser la logique métier existante intacte et confiner le nouveau code à une fine couche de sérialisation a limité les endroits où de nouveaux bugs pouvaient se cacher.

Avant de mettre hors service un système qui fonctionne, faites répondre le remplaçant à chaque requête en parallèle et comparez sa réponse à celle du système en place — les bugs apparaissent pendant que l'ancien système sert encore la réponse.

Le déploiement par comparaison en miroir a permis de détecter plusieurs bugs critiques avant qu'ils n'atteignent les utilisateurs, et SoundCloud a fait monter le service d'autorisation de pistes à 100 % de trafic Twirp sans aucune panne ni aucun bug du premier coup. La bande passante entre les deux services a chuté de plus de 40 % grâce au passage du JSON au protobuf binaire, et l'équipe a supprimé tout son code de sérialisation JSON personnalisé pour le service. SoundCloud a ensuite converti ses autres services à Twinagle et en a fait la solution par défaut pour tous les nouveaux services à l'avenir.

VÉRIFIEZ LES SOURCES

Les sources

  1. Announcing Twinagle: Twirp and Protobuf for Finagle SoundCloud Engineering · developers.soundcloud.com ·