Accueil Nos publications Blog Azure Service Fabric : Le PaaS v2 de Microsoft

Azure Service Fabric : Le PaaS v2 de Microsoft

MS-Azure_rgb_Blk Avec la //Build/ 2015, Microsoft Azure a aussi eu le droit à son lot de nouveautés, notamment Azure Service Fabric, annoncé par Marc Russinovich sur le blog Azure. Le but de ce service est, entre autres, de diminuer la complexité des applications extrêmement scalables. Pour réaliser cela, Azure Service Fabric se base sur un système de développement en mode microservices que l’on peut héberger dans Azure.

Ce service permet de gérer facilement le cycle de vie, la haute disponibilité, la gestion de version et la montée en charge de chacun des microservices indépendamment les uns des autres.

Nous verrons dans cet article ce qu’est un microservice et comment développer une application complexe avec Azure Service Fabric, en faisant un parallèle avec la plateforme de PaaS classique d’Azure qu’est Cloud Services.

Un petit historique de ce service

Si vous avez suivi l’actualité Azure depuis son début, vous n’êtes pas sans savoir que la plateforme a beaucoup évolué au cours du temps et que de nombreux projets à ce jour l’utilisent avec succès. Par ailleurs, vous pouvez retrouver différents « Case Studies » sur ce lien et croyez-moi, il existe beaucoup d’autres projets d’envergure qui tournent dessus. Pour cela, Microsoft a développé des outils internes dans le but d’optimiser la gestion de ses différents services. Azure Service Fabric est à la base un de ces outils internes, qui est utilisé et a mûri depuis presque 5 ans, selon Mark Russinovich lors d’une de ses présentations à la //Build/. Il est notamment utilisé pour faire tourner :

  • Azure Core Infrastructure : Plusieurs milliers de machines
  • Azure DocumentDB : Des milliards de transactions par semaine
  • Intune : 800 000 périphériques enregistrés
  • Azure SQL Database : 1,4 million de bases de données de tailles variables
  • Event Hubs : 20 milliards de messages par jour

Alors, 5 ans pour sortir un produit au grand public, c’est beaucoup, me direz-vous. Sachez qu’en fait ce produit a eu des prémices au niveau du grand public, notamment avec le projet Orléans qui est Open Source depuis la fin de l’année dernière, et qui est notamment utilisé dans la conception du backend du jeu Halo. Alors, effectivement ce n’est pas Azure Service Fabric, cependant il y a des concepts qui sont similaires, en particulier la notion de microservices et la gestion de la communication entre les services.

Un microservice pour Azure Service Fabric ? Mais qu’est-ce donc ?

Avant toute chose, un microservice ce n’est pas quelque chose de dédié à Service Fabric, mais un modèle d’architecture qui existe depuis un certain temps. Par ailleurs, c’est assez en vogue chez les développeurs Java. On en parlait déjà lors du Devoxx 2014.

Au niveau d’Azure Service Fabric, un microservice correspond à ces critères :

  • Il a une logique et un état indépendants versionnés, déployés, et scalables
  • Il a un nom unique qui peut être résolu de la manière suivante fabric:/myapp/myservice
  • Il peut interagir avec les autres microservices définis par des interfaces via un protocole de communication de type REST soit via un client HTTP ou un client WCF
  • Il a une tolérance de panne, c’est-à-dire qu’il garde une logique identique en cas de panne
  • Il est hébergé dans un conteneur qui contient le code et la configuration de celui-ci
  • Il peut être écrit dans différents langages et framework (.Net, Java, Node.js)
  • Il peut être développé par une petite équipe de développeurs, puisqu’il est indépendant et qu’il ne communique que via des interfaces.

Sur Azure, il existe de deux types de microservices :

  • Stateless microservice
    • Ne contient pas d’état, ou alors il peut être retrouvé par une source de données externes
    • Il peut être multi-instances sans incidence sur le code
    • Typiquement, il s’agit de frontend web, de gateway, d’Azure Cloud Services, etc …
  • Stateful microservice
    • A une gestion d’état qui lui est propre
    • Peut contenir plusieurs instances qui sont consistantes et qui partagent les mêmes données grâce à la réplication et à la persistance locale.
    • Typiquement il s’agit de sessions utilisateurs, de documents, de bases de données, de paniers dans un site e-commerce, de workflows, etc…

Les promesses d’Azure Service Fabric

Nous avons vu la définition d’un microservice au sein d’Azure Service Fabric et l’utilisation de ce service au sein d’Azure. Voyons ce que nous offre Azure Service Fabric et ce que la plateforme offre aux développeurs pour améliorer leur quotidien et accélérer les développements.

Tout d’abord, il faut savoir qu’Azure Service Fabric est conçu pour fonctionner aussi bien sur Azure que sur Azure Stack, la plateforme Azure « on-premise ».

Azure Service Fabric propose:

  • Une gestion de la haute disponibilité des services
  • Un modèle de programmation simple
  • La possibilité d’avoir des opérations hybrides
  • Une haute densité des services
  • Une scalabilité des services à grande échelle
  • Un partitionnement des données
  • Une gestion fine des mises à jour que ce soit en upgrade ou en downgrade
  • Une faible latence entre les services
  • Un monitoring simple de la santé de vos services
  • Un démarrage et un arrêt rapide des services
  • La gestion du Load balancing des services
  • L’orchestration et la gestion du cycle de vie du conteneur.
  • Une gestion de récupération automatique des services
  • Un système de réplication et de gestion de failover

En résumé, Microsoft Azure Service Fabric en un slide, c’est ça :

microservices

Démarrer avec Azure Service Fabric

Installation de votre environnement de travail

Nous passerons vite sur cette partie car elle est déjà détaillée sur le site de Microsoft.

Sachez cependant que les prérequis sont au minimum Windows 8 ou Windows Server 2012 R2 et Visual Studio 2015 RC. Bien entendu, tout est compatible avec Windows 10 Technical Preview si vous êtes un afficionado des previews.

Petite astuce tout de même, je vous conseille de bien garder les scripts PowerShell DevClusterSetup.ps1 et CleanCluster.ps1 sous la main car le cluster en local commence à prendre beaucoup de place si vous faîtes des gros tests ou beaucoup d’applications. Et pour information, le script CleanCluster vous stoppe votre cluster en plus de le purger. Il faut donc relancer le DevClusterSetup pour que vos projets fonctionnent à nouveau. Pour rappel, ces scripts se trouvent dans le dossier C:\Program Files\Microsoft SDKs\Service Fabric\ClusterSetup\ et votre SSD vous remerciera.

Création de notre premier service

Maintenant, dans Visual Studio 2015, que vous démarrerez en tant qu’administrateur bien entendu, vous avez une sous-partie Service Fabric dans la partie Cloud, comme on peut le voir ci-dessous :

quick start

Pour commencer, nous allons créer une application avec un service Stateless que nous appellerons Gateway.

Après avoir fait les mises à jour des packages NuGet, installé la dernière version des différentes librairies et renommé l’application afin que son nom nous convienne, nous nous retrouvons avec une solution de ce type.

solution

A l’heure actuelle, nous avons 2 projets qui sont :

  • DemoBlog.ServiceFabric.Application
  • DemoBlog.ServiceFabric.Gateway

Le premier est le projet qui nous permet de packager, déployer et référencer nos services. A l’intérieur de celui-ci, nous aurons donc des scripts powershell qui, à mon avis, auront disparu dans une future version et une ApplicationManifest.xml que nous détaillerons plus tard.

Le deuxième est notre application Gateway. Il s’agit d’une Console qui contient un début de code pour faire tourner notre application et un dossier Package qui contient, quant à lui, un dossier de config et un ServiceManifest.xml que nous détaillerons par la suite. Pour le code, nous avons une classe qui hérite de StatelessService et un fichier EventSource qui permet d’avoir du monitoring via ETW. Mis à part cela, ce projet ne fait rien sauf incrémenter un compteur, autant dire un code de haut vol pour commencer à travailler. Pour la suite, je vais mettre en place Owin et Web Api sur notre Gateway afin de gérer nos appels. Pour cela, je vais suivre le tutoriel qu’on peut retrouver sur la documentation Microsoft

A ce stade, nous avons donc un service Stateless qui héberge une WebApi. Avant d’aller plus loin, voyons comment cela se comporte dans notre outil. Pour cela, nous allons ouvrir Service Fabric Explorer. Cet outil se trouve dans le même dossier que les scripts powershell que je vous ai conseillé de garder. Nous avons donc la distribution de notre service ainsi qu’un descriptif de ce dernier comme nous pouvons le voir ci-dessous :

service fabric explorer

Création de services statelesss

Désormais, nous avons une gateway, nous allons ajouter des services. Pour cela, il vous suffit de faire un clic droit sur votre application, de sélectionner « New Service Fabric » et d’y ajouter un service. Pour mon cas, nous allons ajouter un deuxième service Stateless qui s’appellera Calculator et nous implémenterons des méthodes pour faire des opérations de base. Outre l’implémentation des services qui n’a rien de compliqué, puisqu’on parle d’opérations mathématiques basiques, le principal challenge est de gérer la communication entre notre Gateway et notre Calculette. Pour cela, Service Fabric nous propose trois solutions simples. Nous pouvons utiliser le système par défaut, utiliser un système de communication soit via http, soit via un channel WCF. Mais il existe un quatrième choix, moins simple, mais qui nous permet d’implémenter nous-mêmes notre communication si on le souhaite. Les différents systèmes sont expliqués sur la documentation Azure, donc je ne reviendrai pas dessus, je vous conseille néanmoins de regarder ce lien

Dans notre cas, nous allons utiliser une implémentation avec WCF, puisque c’est celle que je considère comme la plus utile actuellement pour de nombreux scénarios d’Azure Service Fabric.
Au niveau de l’implémentation, nous devons donc créer notre listener au niveau de notre service de calcul ainsi qu’un client afin de pouvoir y accéder comme nous pouvons le voir ci-dessous :
Notre listener :

code 1

Une classe utilitaire pour le listener et le client, qui contient aussi l’url unique de notre application et la gestion du binding. A noter que l’url de l’application est simple car, ici encore, nous sommes sur un service stateless qui n’est pas partitionné :

code 2

Et pour finir notre client WCF :

code 3

Effectivement, dans l’approche cela est plutôt simple à mettre en place, puisque la gestion du WCF et des différents proxys est réalisée par le SDK. Mais si vous avez regardé les différents moyens de communiquer entre les services, vous verrez que celui par défaut est encore plus simple à mettre en œuvre. Il est cependant moins personnalisable au niveau du binding et en termes de sécurité.

A ce stade, si nous comparons avec des Cloud Services classiques, nous voyons que la communication entre deux services stateless est beaucoup plus simple qu’avant, puisque nous ne passons pas par un système tiers, telle qu’une file ou un système de stockage des messages à traiter, ce qui engendre inévitablement des meilleurs temps de réponse.

Des services statefull

Un des autres avantages d’Azure Service Fabric est l’apport des services stateful que l’on n’avait pas dans le PaaS v1 d’Azure. Il est vrai que, dans une architecture Azure PaaS v1, nous avions appris à s’épargner la gestion et la maintenance des services stateful, mais dorénavant Azure Services Fabric change la donne. Je ne vais pas vous réexpliquer l’utilité des services Stateful mais je vais vous parler des nouvelles collections introduites par Azure Service Fabric.

Pour cela, je vais ajouter un historique de calcul à ma démonstration. Ainsi, à chaque appel à mon service, je vais stocker les différentes opérations de calcul que je réalise. Afin de stocker ces différents éléments, je vais utiliser une ReliableDictionary, qui est une des deux collections possibles pour stocker des éléments de manière « reliable » ; la deuxième étant une IReliableQueue. Au niveau de l’implémentation, nous aurons donc quelque chose de ce type pour la manipulation de notre dictionnaire :

code 4

Ici, pour ce service, j’ai choisi la stack de communication de base, puisqu’il est possible de faire ce choix pour chaque microservice. Pour vos projets concrets, je vous conseille d’être cohérents dans le choix de votre stack de communication.

code 5

Comme on peut le voir ci-dessus, la gestion de la communication avec la stack par défaut est assez simple d’utilisation, même si dans ce cas précis j’utilise un déploiement avec plusieurs partitions. J’aurais cependant très bien pu utiliser une SinglePartition.

Les actors Stateful et Stateless

Dans cette solution, je ne vais pas les implémenter, mais sachez que mon service stateless aurait très bien pu être un Actor Stateless. Cependant, mon service stateful doit rester en tant que service. Pourquoi cela ? Durant la conception de votre application si vous devez choisir entre un Actor et un Service, voici un tableau qui vous permettra de comparer les possibilités qu’ils offrent indépendamment les uns des autres.

Reliable Actors API Reliable Service APIs
Est utilisé pour résoudre de multiples tâches indépendantes et logiques Vous devez maintenir une logique entre plusieurs composants
Vous voulez travailler de manière monothreadée tout en étant capables de monter en charge en conservant la consistance des états Vous voulez utiliser les Reliables collections pour stocker et manager les différents états
Vous voulez que le SDK gère la concurrence et la granularité des états Vous voulez contrôler la granularité et gérer la concurrence de vos états
Vous voulez que la plateforme gère la communication entre les services Vous voulez gérer la communication entre les services et gérer le partitionnement de ceux-ci.

Pour ce qui est de la communication entre un service et un acteur, voici comment on peut appeler notre acteur :

code 6

Pour aller plus loin

Vous avez vu comment développer vos différents services dans Azure. Nous n’irons pas beaucoup plus loin sur les détails d’implémentation des services dans cet article. Néanmoins, sachez que dans cet exemple de code, j’instancie tous mes services au déploiement de l’application. Il est cependant possible de faire cela à la volée via le code, ce qui peut se révéler utile, notamment lorsque vous voulez créer des ressources dédiées à une session utilisateur par exemple. Pour réaliser cela, il faut :

  • Dans votre fichier ApplicationManifest.xml, déclarez uniquement les services que vous voulez déployer par défaut, donc supprimez les services que vous ne voulez pas au démarrage dans la partie « DefaultServices ». Néanmoins, laissez bien sa déclaration, sinon vous ne pourrez pas l’utiliser dans l’application.
  • Au sein de votre code, il vous suffit de créer le service à la volée via l’objet FabricClient comme ceci :

code 7

Attention cependant, une création à la volée d’un service signifie un déploiement de celui-ci. Il n’est donc pas disponible immédiatement après le retour de la tâche.

Par ailleurs, dans cet article, je n’ai pas détaillé les problématiques de déploiement car, à ce jour, il n’est pas possible de déployer sur Azure avec la public preview.

En conclusion

Cette nouveauté apportée par Azure offre une nouvelle façon d’aborder la conception d’application, ainsi que de nouveaux enjeux. Le fait devoir découper notre application en microservices apporte une plus grande souplesse dans notre code et dans le déploiement de nos applications sur Azure, d’autant plus que, pour le développement, il est très simple de distribuer chaque microservice à une équipe distincte. A mon sens, ce type d’architecture est à prendre en considération pour la plupart des projets Cloud d’envergure moyenne et plus.

Retrouvez les sources de la démo sur Github.

J’en profite enfin pour vous annoncer, si vous n’étiez pas déjà au courant, qu’une soirée autour d’Azure est prévue le 1er juillet chez SOAT et l’un des sujets est Azure Service Fabric et le projet Oxford. Vous pouvez vous inscrire ici.