BT

Diffuser les Connaissances et l'Innovation dans le Développement Logiciel d'Entreprise

Contribuez

Sujets

Sélectionner votre région

Accueil InfoQ Articles Microservices Dans Le Cloud, Première Partie

Microservices Dans Le Cloud, Première Partie

Points Clés

  • Comprendre ce que sont les microservices
  • Comprendre les couches dans un microservices
  • Comment utiliser Eclipse Microprofile
  • Les avantages de Eclipse Microprofile
  • Microservices intégrés au cloud

Les micro-services sont une architecture logicielle dont les systèmes sont un ensemble de plusieurs services indépendants. Chaque service a une orientation métier spécifique et communique avec les autres par le biais d'un protocole linguistique agnostique, tel que REST. L'initiative Eclipse MicroProfile propose une solution en Java pour mettre en oeuvre une architecture microservices. Elle est basée sur un sous-ensemble d'APIs de Jakarta EE. Cet article donnera un aperçu des meilleures pratiques pour travailler avec les microservices Java sur le Cloud.

Un peu de contexte

Nous allons créer une architecture de microservices basée sur le contexte des villes, des sessions et des conférenciers aux conférences sur l’informatique.

Pour gérer les conférences dans le cadre d’un voyage en Amérique latine, nous utiliserons trois microservices :

  • Conférencier : Le service de conférenciers qui s'occupe du nom, de la biographie et des liens vers les réseaux sociaux de chaque conférencier.
  • Conférence : Le service de conférences qui travaille avec les conférences, en s’occupant de leur nom, de leur ville et de l'année de la conférence.
  • Session : Le service de session qui gère le nom, le titre, la description et les informations sur la conférence et le conférencier.

Bases de données

Chaque base de données a sa structure et son comportement particulier : nous utiliserons donc des bases de données différentes en fonction de chaque service. En effet, c'est l'avantage des microservices, chaque service peut utiliser n'importe quelle technologie conforme à ses exigences sans affecter les autres services. Chaque microservice utilise une base de données adaptée à son cas d’usage particulier :



PostgreSQL (également connu sous le nom de Postgres). Système de gestion de base de données relationnelle libre et gratuit qui met l'accent sur l'extensibilité et la conformité aux normes techniques. Il est conçu pour gérer toute une gamme de charges de travail, des machines individuelles aux entrepôts de données ou aux services Web avec de nombreux utilisateurs simultanés.



MongoDB. Base de données multiplateforme orienté document. Classé comme un serveur de base de données NoSQL, MongoDB utilise des documents de type JSON avec schéma.



Elasticsearch. Un moteur de recherche basé sur la bibliothèque Lucene. Elasticsearch fournit un moteur de recherche full text multi-tenant distribué avec une interface Web HTTP et des documents JSON sans schéma. Elasticsearch est développé en Java.

Implémentations d'Eclipse MicroProfile

La communauté MicroProfile, relativement nouvelle, se consacre à la mission de développer les architectures d’entreprises basées sur les microservices en Java. Leur but ? Une plate-forme pour microservices portable sur plusieurs environnements d'exécution. Actuellement, IBM, Red Hat, Tomitribe, Payara, la London Java Community (LJC) et SouJava mènent le peloton dans ce groupe.



Thorntail propose une approche innovante du packaging et de l'exécution des applications Java EE en les empaquetant avec juste le nécessaire pour une exécution de votre application sur un serveur avec un simple "java -jar".



D'une taille inférieure à 70 Mo, Payara Micro - la plate-forme middleware légère et open source de choix pour les déploiements de micro-services Java EE (Jakarta EE) conteneurisés - ne nécessite aucune installation ou configuration et ne nécessite pas de réécriture de code.



KumuluzEE développe des microservices avec les technologies Java EE /Jakarta EE et les étend avec Node.js, Go et d'autres langagees. Il migre les applications Java EE existantes vers les microservices et l'architecture cloud native.



Apache TomEE utilise plusieurs projets Apache, dont Apache Tomcat et Apache OpenWebBeans. Une de ces versions inclut une implémentation d'Eclipse MicroProfile.

Rassembler les technologies

Notre projet comporte quatre volets :

  • KumuluzEE s'occupera du microservice Session. Les utilisateurs voudront rechercher les détails de sessions, comme trouver des sessions qui parlent soit d'Eclipse Microprofile, soit de Jakarta EE. Pour répondre à cette demande, le projet utilisera un NoSQL qui est aussi un moteur de recherche puissant (oui, nous parlons ici d'Elasticsearch).

  • Thorntail s'occupera du microservice Conférencier, le service le plus simple qui gérera les détails du conférencier. Ce service fonctionnera avec PostgreSQL.
  • Payara Micro se chargera du microservice Conférence. Ce service est fortement lié à KumuluzEE et Thorntail. Pour créer une conférence, nous avons besoin à la fois de sessions et de conférenciers. MongoDB semble s'adapter facilement à ce service car nous pouvons utiliser le concept de sous-documents pour créer une liste de présentations et de conférenciers dans l'entité Conférence, au lieu de faire cette relation comme dans une base de données relationnelle.
  • Apache TomEE représente le client qui demandera des informations aux autres services. Il utilise HTML 5 dans le front-end.

Eclipse MicroProfile et Jakarta à la rescousse !

Quels sont les avantages significatifs d'Eclipse MicroProfile ? Tout d'abord, il applique des normes sur Jakarta EE, telles que CDI, JAX-RS, et JSON-P.

Pour se connecter à PostgreSQL ou à toute base de données relationnelle, il existe la spécification JPA qui décrit la gestion des données relationnelles dans les applications utilisant la plate-forme Java. Pour communiquer avec les bases de données NoSQL, nous utiliserons la spécification NoSQL de Jakarta (pas encore sa version finale, mais nous espérons qu'elle sera bientôt disponible).

Côté client, nous utiliserons Eclipse Krazo avec une extension HTML 5, en utilisant Thymeleaf comme moteur de template. Pour le moment, le client n'a pas de base de données ; il ne communiquera qu'avec les services pour obtenir les valeurs, puis les afficher dans le navigateur. Par conséquent, il utilisera Eclipse MicroProfile Rest Client, qui fournit une approche sûre pour appeler les services RESTful via HTTP.

Des couches, des couches et encore des couches

Le nombre de couches dans une application est toujours un sujet colossal quand on parle de microservices. Les couches sont essentielles pour partager les rôles et écrire du code propre, tout en conservant les différents modèles construits suivant cette approche, comme le MVC.

Cependant, un grand nombre de couches est également difficile à conserver et à maintenir : nous devons faire attention aux couches qui existent pour invoquer d’autres couches. Sinon, au lieu d'un MVC, nous allons recréer le motif de l'oignon, où on pleure à chaque fois qu’on passe par une couche. Il n'y a pas de formule magique pour déterminer le nombre de couches nécessaires. Cela sera plutôt basé sur la complexité des règles métier et sur la façon dont le code d'infrastructure peut nous donner l'architecture la plus propre.

Dans notre projet, nous avons trois couches :

  • L'entité. La première instance du métier et où réside le domaine. Ces entités doivent suivre un modèle riche ; nous pouvons rendre ces entités agnostiques à une base de données, mais pour cette fois, nous allons rester simples et utiliser l'entité fortement associée avec la base de données.
  • L'objet de transfert de données (DTO). Une classe pour permettre le transfert de valeurs entre le contrôleur et l'entité. Son but principal est d'éviter que cette entité ne devienne un modèle anémique, car certains frameworks peuvent nécessiter des méthodes getter et setter de sérialisation, ce qui signifie généralement une faible encapsulation.
  • Le contrôleur. Le lien entre la vue et le modèle. Il ne fait que manipuler le flux entre eux. À quelques exceptions près, il doit rester aussi propre que possible - vous vous souvenez de la règle de cohésion élevée, n'est-ce pas ?

Est-ce qu’il y a un cloud ? Ou n’est-ce qu’une illusion ?

La gestion des bases de données, du code et des intégrations est toujours difficile, même sur le cloud. En effet, le serveur est toujours là, et quelqu'un doit le surveiller, exécuter des installations et des sauvegardes, et maintenir sa santé en général. Et l'APP à douze facteurs exige une séparation stricte entre la configuration et le code.

Heureusement, Platform.sh fournit un PaaS qui gère les services, tels que les bases de données et les messages entrants, avec prise en charge de plusieurs langues, dont Java. Tout repose sur le concept d'Infrastructure as Code (IaC), avec la gestion et l'approvisionnement des services par le biais de fichiers YAML.

Dans d'autres articles, nous avons mentionné comment cela se fait sur Platform.sh principalement avec trois fichiers :

  • Un pour définir les services utilisés par les applications (services.yaml).
elasticsearch:
	type: elasticsearch:6.5
	disk: 512
	size: S
mongodb:
	type: mongodb:3.6
	disk: 512
	size: S
postgresql:
	type: postgresql:11
	disk: 512
	size: S
"https://{default}/conferences":
	id: conference
	type: upstream
	upstream: "conference:http"

"https://{default}/sessions":
	id: session
	type: upstream
	upstream: "session:http"

"https://{default}/speakers":
	id: speaker
	type: upstream
	upstream: "speaker:http"

"https://{default}/":
  type: upstream
  upstream: "client:http"

"https://www.{default}/":
  type: redirect
  to: "https://{default}/"

Il est important de souligner que les routes servent pour des applications que nous voulons partager publiquement. Par conséquent, si nous voulons que le client n'accède qu'à ces microservices, nous pouvons supprimer son accès aux conférences, sessions et conférenciers du fichier routes.yaml.

Platform.sh simplifie la configuration d'applications individuelles et de microservices avec le fichier `.platform.app.yaml`. Contrairement aux applications monolithiques, chaque application microservice aura son propre répertoire à la racine du projet et son propre fichier `.platform.app.yaml` associé à cette application unique. Chaque application décrira son langage et les services auxquels elle se connectera. Puisque l'application client coordonnera chacun des microservices de notre application, elle spécifiera ces connexions en utilisant le bloc `relationships' de son fichier `.platform.app.yaml'.

name: client
type: "java:8"

disk: 800

# The hooks executed at various points in the lifecycle of the application.
hooks:
	build: |
  	mvn -Dhttp.port=8888 -Dspeaker.service=http://speaker.internal/ -Dconference.service=http://conference.internal/ -Dsession.service=http://session.internal/ -DskipTests clean install tomee:exec

relationships:
   speaker: speaker:http
   conference: conference:http
   session: session:http

web:
	commands:
    	start: |
      	mv target/ROOT-exec.jar app/ROOT-exec.jar
      	java -Xmx1024m -jar  app/ROOT-exec.jar

Avec les exigences définies dans le fichier YAML de l'application, nous pouvons extraire l'information de l'environnement. Oui, nous suivons les douze facteurs qui séparent le code de la configuration.

echo $PLATFORM_RELATIONSHIPS | base64 --decode | json_pp

{
   "session" : [
  	{
     	"service" : "session",
     	"rel" : "http",
     	"scheme" : "http",
     	"cluster" : "dvtam6qrvyjwi-master-7rqtwti",
     	"port" : 80,
     	"ip" : "169.254.159.17",
     	"host" : "session.internal",
     	"hostname" : "owh4yp4z3tbt3x7fajdexvndpe.session.service._.eu-3.platformsh.site",
     	"type" : "java:8"
  	}
   ],
   "speaker" : [
  	{
     	"scheme" : "http",
     	"rel" : "http",
     	"service" : "speaker",
     	"type" : "java:8",
     	"hostname" : "4edz7hoi7xx4bnb7vkeopzltc4.speaker.service._.eu-3.platformsh.site",
     	"host" : "speaker.internal",
     	"port" : 80,
     	"cluster" : "dvtam6qrvyjwi-master-7rqtwti",
     	"ip" : "169.254.245.54"
  	}
   ],
   "conference" : [
  	{
     	"service" : "conference",
     	"rel" : "http",
     	"scheme" : "http",
     	"port" : 80,
     	"cluster" : "dvtam6qrvyjwi-master-7rqtwti",
     	"ip" : "169.254.81.85",
     	"host" : "conference.internal",
     	"hostname" : "3aora24tymelzobulrvgc5rscm.conference.service._.eu-3.platformsh.site",
     	"type" : "java:8"
  	}
   ]
}

La bonne nouvelle à propos de ces informations est que nous n'avons pas besoin de manipuler ou d'extraire les données manuellement, et c'est pourquoi nous avons le lecteur de configuration.

name: conference

type: "java:8"

disk: 800

relationships:
  mongodb: 'mongodb:mongodb'

web:
	commands:
    	start: java -jar -Xmx1024m target/conference-microbundle.jar --port $PORT

En utilisant le lecteur de configuration Java, nous pouvons lire à partir de l'environnement et retourner un client tel que MongoDB, Datasource, ou Elasticsearch. Par exemple, sur l'application.yaml des conférences, nous avons besoin d'un accès à MongoDB, à partir duquel nous pouvons extraire et convertir ces informations en une instance MongoClient et les rendre disponibles via CDI.

import com.mongodb.MongoClient;
import jakarta.nosql.document.DocumentCollectionManager;
import org.jnosql.diana.mongodb.document.MongoDBDocumentCollectionManagerFactory;
import org.jnosql.diana.mongodb.document.MongoDBDocumentConfiguration;
import sh.platform.config.Config;
import sh.platform.config.MongoDB;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;

@ApplicationScoped
public class MongoConfig {

	@Produces
	public DocumentCollectionManager getManager() {
    	Config config = new Config();
    	final MongoDB mongo = config.getCredential("mongodb", MongoDB::new);
    	final MongoClient mongoClient = mongo.get();
    	MongoDBDocumentConfiguration configuration = new MongoDBDocumentConfiguration();
    	MongoDBDocumentCollectionManagerFactory factory = configuration.get(mongoClient);
    	return factory.get(mongo.getDatabase());
	}
}

Attendez ! Où est le code ?

Pour éviter que cet article ne devienne un livre, divisons-le en plusieurs parties. La première était un aperçu des avantages de l'utilisation des microservices - pourquoi les utiliser et comment Eclipse MicroProfile et Platform.sh peuvent vous aider à les réaliser. Nous avons déjà parlé d'Eclipse MicroProfile, JPA, Eclipse Krazo et Eclipse JNoSQL. Vous pouvez revoir ces articles, et, si vous ne vous souciez pas des spoilers, consultez le code de toute cette série sur GitHub.

Sinon, restez à l'écoute pour la seconde partie, où nous détaillerons la conception du code et l'expliquerons étape par étape.

A propos de l'auteur

Otavio SantanaEncourageant les développeurs dans le monde à construire de meilleurs logiciels plus rapidement, capables d’évoluer dans le Cloud, Otavio est un ingénieur développeur passionné spécialisé en technologies Cloud et Java. Il a de l'expérience principalement dans la persistance des applications multi-technos et de haute performance en finances, médias sociaux et e-commerce. Otavio fait partie de Groupes Experts et Leaders dans plusieurs comités exécutifs JSRs et JCP. Il travaille sur plusieurs projets de la Fondation Apache et Eclipse, comme par exemple Apache Tamaya, MicroProfile, ou Jakarta EE, où il dirige la première spécification de Jakarta EE avec Jakarta NoSQL. JUG Leader et speaker international aux conférences JavaOne et Devoxx, Otavio a reçu de nombreux prix pour ses contributions OSS, tels que le JCP Outstanding Award, Membre de l’année et innovateur JSR, Duke’s Choice Award, ainsi que Java Champion Awards, pour n’en citer que quelques uns.

 

Evaluer cet article

Pertinence
Style

Contenu Éducatif

BT