Tandis que presque toutes les équipes de développement ont à un moment donné considéré s'orienter vers les microservices, les avantages de ceux-ci sont mitigés par de sérieuses contreparties. A la QCon de Londres, Alexandra Noonan (ndt : ingénieur backend chez Segment) a raconté comment l'entreprise Segment a décomposé son monolithe en microservices, puis quelques années plus tard est revenu à une architecture monolithique. De ses propres mots : "si les microservices sont mal implémentés ou utilisés comme rustine sans régler les vrais problèmes du système, vous serez incapable de faire de nouveaux développements, car vous serez noyé dans la complexité"
Les Microservices ont été introduits pour la première fois afin de régler des problèmes de localisation des pannes dans le monolithe de Segment. Cependant, alors que l'entreprise devenait de plus en plus prospère, et utilisait de plus en plus de services externes, le surcoût engendré par la maintenance des microservices est devenue écrasant. La décision de revenir à un monolithe s'est faite avec la perspective d'une architecture nouvelle, prenant en compte les problèmes de scalabilité accompagnant la croissance d'une entreprise. Bien que sacrifiant la modularité, l'isolation et la lisibilité, le monolithe réglait le problème majeur de surcoût d'exploitation et a permis à l'équipe d'ingénieurs de reprendre le développement de nouvelles fonctionnalités métiers.
Alexandra Noonan nous a expliqué les différentes étapes clefs de l'évolution de l'architecture chez Segment. Les problèmes rencontrés et les décisions prises résonnaient familièrement aux oreilles de tout développeur senior. Ce n'est que parce que nous avons du recul que nous réalisons clairement quelles décisions auraient été meilleures. Alexandra Noonan nous a expliqué chronologiquement chaque décision cruciale, en faisant part du pour et du contre à chaque étapes de l'architecture.
En 2013, Segment a démarré avec une architecture monolithique. Cela permettait des coûts d'exploitation réduits, mais n'apportait pas d'isolation système. Les fonctionnalités de Segment s'appuient sur l'intégration de données de différents fournisseurs. Dans le monolithe, des problèmes de connexions à un fournisseur peuvent avoir un effet négatif sur l'ensemble des connexions et sur le système entier.
Le manque d'isolation à l’intérieur du monolithe fut adressé par l'adoption des microservices, avec un "service worker" par destination (fournisseur). Les Microservices ont également amélioré la modularité et la lisibilité au travers du système, permettant à l'équipe de monitorer les queues et identifier les problèmes facilement. Alexandra Noonan nous a fait remarquer que l'on peut concevoir un monolithe en le rendant plus lisible, mais que les microservices ont cette qualité par défaut. Par contre, ceux-ci engendrent un surcoût sur les opérations et posent problème quant à la réutilisabilité du code.
Lors d'une période de très forte croissance chez Segment, autour de 2016-2017, cinquante nouvelles destinations ont été ajoutées, environs trois par mois. Avoir un dépôt pour chaque service était gérable pour quelques "service workers", mais c'est devenu un problème lors du changement d'échelle. Des librairies partagées ont été créées pour apporter de la cohérence entre les différents "workers". Cependant, cela a créé un nouveau goulot d'étranglement, où les modifications sur le code partagé pouvaient entraîner une semaine de développement principalement dû aux contraintes sur les tests. La création de versions différentes de ces librairies partagées ont permis d'apporter des évolutions plus rapidement, mais en contre-partie rendaient nul les bénéfices qu'elles sont censées apporter.
Alexandra Noonan a souligné que leur approche des microservices comme une solution miracle avait eu ses limitations. Comme il a fallu tellement d'efforts pour simplement ajouter de nouveaux services, leurs implémentations n'ont pas été customisées. Par exemple, une seule règle d'auto-scalabilité fut appliquée à l'ensemble des services, alors que chacun d'eux avaient des besoins CPU très différents. Aussi, une solution adéquate pour mettre en place une vraie localisation des pannes aurait pu être d'avoir un microservice par queue et par client, mais cela aurait nécessité plus de 10 000 microservices.
La décision en 2017 de revenir à un monolithe prenait en compte toutes les contreparties, y compris être prêt à perdre les bénéfices des microservices. L'architecture qui en résulta, nommée Centrifuge, est capable de prendre en charge des milliards de messages par jours à envoyer à des dizaines d'API publiques. Il y a maintenant un unique dépôt de code et tous les "workers" utilisent la même version de la librairie commune. Le plus gros "worker" est plus à même d'absorber les pics de charge. Ajouter de nouvelles destinations n'engendre plus une surcharge opérationnelle et les déploiements ne prennent que quelques minutes. L'équipe a estimé que tous ces bénéfices justifient la perte de modularité, d'isolation système et de lisibilité qui étaient les apports des microservices.
Les participants de la QCon discutant de la présentation, faisaient des commentaires semblables à ceux d'ingénieur rejoignant un projet avec un gros passif. Des remarques telles que : "Bien-sûr, on ne doit pas faire ce qu'ils ont fait", contrées par des voix d'expérimentées, rappelant que la plupart des décisions sont faites avec les meilleurs informations disponibles sur le moment. L'une des choses à retenir étant que dépenser quelques jours ou semaines à approfondir une analyse peut permettre d'éviter une situation qui prendrait des années à rattraper.