Das Backend von SoundCloud lief auf Microservices mit handgebauten REST/JSON-Schnittstellen – leicht zu debuggen, aber die Konventionen jedes Endpunkts blieben dem Team überlassen, das ihn baute: HTTP-Methode, JSON-Feldnamen, Zeitstempelformate, Fehlerstrukturen. Interne Richtlinien halfen nur bedingt: Ein Client sandte einmal camelCase-Felder an einen Server, der snake_case erwartete, und verursachte einen Ausfall, und um einen Endpunkt zu verstehen, musste man Anwendungscode lesen statt eines Vertrags.
SoundCloud baute Twinagle, eine Scala/Finagle-Implementierung von Twitchs Twirp-RPC-Protokoll, damit Ingenieure eine API einmal in Protobuf definieren und Server- und Client-Code daraus generieren konnten. Sie migrierten zuerst ihren stark frequentierten Dienst zur Track-Autorisierung. Statt direkt umzustellen, betrieben sie REST und Twirp parallel hinter einem prozentbasierten Flag: Bei niedrigen Rollout-Prozentsätzen wurden beide Endpunkte aufgerufen und verglichen, wobei nur die REST-Antwort zurückgegeben wurde, sodass Abweichungen als protokollierte Diskrepanzen und nicht als nutzerseitige Fehler auftauchten.
Verkehr an den neuen Endpunkt spiegeln, ihn vergleichen, dann umstellen
Das Generieren von Server- und Client-Code aus einem einzigen Protobuf-Vertrag beseitigte die Klasse von Fehlern, die entsteht, wenn Teams ihre eigenen JSON-Feldbenennungs- und HTTP-Konventionen erfinden.
Beide Endpunkte bei einem kleinen Verkehrsprozentsatz parallel laufen zu lassen, bevor umgestellt wurde, ermöglichte es dem Team, Antwortabweichungen zu erkennen, ohne dass ein Nutzer eine falsche Antwort sah.
Mit einem Dienst mit einem einzigen Client und hohem Verkehrsaufkommen zu beginnen, hielt die Integrationsfläche der ersten Migration klein und bewies Twinagle zugleich unter realer Last.
Die bestehende Geschäftslogik unangetastet zu lassen und neuen Code auf eine dünne Serialisierungsschicht zu beschränken, begrenzte, wo sich neue Fehler verstecken konnten.
Bevor man ein funktionierendes System außer Betrieb nimmt, sollte der Ersatz jede Anfrage parallel beantworten und mit dem amtierenden System vergleichen – die Fehler treten zutage, während das alte System noch die Antwort liefert.
Der Rollout mit Shadow-Vergleich fing mehrere kritische Fehler ab, bevor sie Nutzer erreichten, und SoundCloud steigerte den Dienst zur Track-Autorisierung auf 100 % Twirp-Verkehr – ohne Ausfälle und ohne Fehler beim ersten Versuch. Die Bandbreite zwischen den beiden Diensten sank um mehr als 40 %, weil von JSON auf binäres Protobuf umgestellt wurde, und das Team löschte seinen gesamten benutzerdefinierten JSON-Serialisierungscode für den Dienst. SoundCloud stellte anschließend seine übrigen Dienste auf Twinagle um und machte es zum Standard für alle neuen Dienste.
DEN BELEGEN FOLGEN
Die Quellen
- Announcing Twinagle: Twirp and Protobuf for Finagle SoundCloud Engineering · developers.soundcloud.com ·