Cet article est notre compte rendu du talk Cloud Native .NET donné par Mark Rendle lors de la conférence NCrafts en mai dernier. Il s’agissait de nous présenter et de mettre en pratique une architecture « Cloud Native » en .Net.

Qu’est-ce que « Cloud Native .NET » ?

Mark Rendle commence par nous donner sa définition du Cloud Native .NET : comme son nom l’indique, ce type de systèmes est hébergé dans le Cloud, mais pas nécessairement Azure. Le fait d’utiliser des technologies .NET ne nous interdit pas de déployer notre système dans AWS, Google, etc.

“In 2018, It’s illegal to make a talk that is not about Microservice”

Mark Rendle

Plus sérieusement, un système dans le cloud est souvent synonyme d’une architecture microservice, c’est-à-dire composé d’un ensemble d’applications s’exécutant dans des conteneurs et consommant des services proposés par les plateformes Cloud comme par exemple des bases de données.

Réaliser un système Cloud Native implique également d’aller au-delà du simple développement d’applications, et de gérer tous les aspects de leur cycle de vie grâce à des pratiques DevOps telles que l’intégration et le déploiement continus, l’Infrastructure as Code, le monitoring des applications et les tests automatisés.

Pourquoi faire du Cloud Native et qu’est-ce que ça apporte ?

Le premier avantage du Cloud est qu’il nous libère de la gestion des serveurs :

  • Plus besoin de salle serveur
  • Plus de gestion de matériel
  • Plus d’OS à mettre à jour

Les fournisseurs de Cloud mettent à disposition énormément d’outils qui permettent d’implémenter très rapidement des fonctionnalités comme le monitoring et l’alerting (ex: Application Insights dans Azure), la sécurisation (HTTPS, authentification avec Azure Active Directory), le déploiement sans interruption de service et l’A/B testing grâce aux slots de déploiements, le load balancing, la persistance de données avec les databases as a service (SQL Server Azure, Amazon Relational Database Service), de l’échange de messages (Bus as a service), etc.

La plupart des composants proposés par le cloud sont nativement scalables. Lorsqu’un système est composé d’une multitude de microservices et que l’un d’eux subit un fort trafic, il est possible de l’upscaler très précisément, lui et lui seul, en multipliant par exemple le nombre de ses instances ou en augmentant les ressources de son conteneur. Dans certains cas le scaling peut même être automatique. Cette fonctionnalité d’adaptation de la charge permet d’optimiser les coûts d’exploitation.

La question que tout le monde se pose : quelle doit être la taille d’un Microservice ?

Réponse de Mark Rendle : « Micro ».

Il est vrai que lorsqu’on développe un microservice, on se demande très rapidement à quel point il doit être petit, ou à partir de quel moment il devient trop gros pour ne plus être considéré comme un microservice et doit donc être découpé en plusieurs microservices. Cela n’a en réalité rien à voir avec la taille du microservice. Dès lors que le service fait correctement le travail pour lequel il a été conçu, d’une façon qui satisfait ses utilisateurs, l’équipe en charge de le développer, et s’il est simple de le déployer et de le tester, s’il est performant et résilient, il s’agit d’un microservice bien fait.
Idéalement, une microservice doit être le plus indépendant possible des autres et doit pouvoir continuer à fonctionner, même de façon dégradée, en cas d’indisponibilité d’une de ses dépendances.

Comment rendre son microservice indépendant des autres ?

Une première étape consiste à faire en sorte que chaque microservice dispose de sa propre source de données, dans la technologie la mieux adaptée à ses besoins (cache, base relationnelle, base NoSql), et qu’aucun autre service n’y ait accès. En effet, si plusieurs services dépendent d’une même base de données, ils seraient tous impactés en cas de problème.

Dans la mesure du possible, privilégier les communications asynchrones entre microservices via un bus de message (RabbitMQ, Azure Service Bus, Amazon SQS) ou des mécanismes de type Publish/Subscribe (Cache Redis). Contrairement à une communication synchrone où l’émetteur attend explicitement que le destinataire lui réponde, dans le cadre d’une communication asynchrone l’émetteur ne fait que poster un message dans une file d’attente. Les destinataires dépilent les messages de cette file à leur rythme, ce qui permet donc également de lisser la charge.

Mise en pratique

Dans la deuxième partie de son talk, Mark Rendle nous a présenté son projet d’application de conférence basée sur une architecture Cloud Native : DeckHub, qui permet de suivre en direct les slides d’une conférence, de les annoter, de poser des questions et de consulter la présentation à postériori.

Cette application illustre les différents aspects décrits précédemment : le découpage d’un système en plusieurs microservices hébergés dans des conteneurs, communiquant de façon asynchrone, capables de fonctionner si l’un des composants est indisponible. L’exemple utilise les technologies  :

  • Aspnet Core 2.1
  • SignalR
  • Redis
  • Azure Service Bus
  • Azure Blob Storage
  • Docker + Kubernetes

Conclusion

Nous avons beaucoup apprécié ce talk, l’un des plus orientés technique de cette édition, et qui offre un très bon aperçu des systèmes Cloud Native et des microservices, avec une approche pragmatique et pratique. Il nous a donné envie de nous prêter à l’exercice, ce qui fera l’objet d’un prochain article.

La vidéo de la présentation

Références

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *