PREMIER MICRO-SERVICE AVEC LE FRAMEWORK SPRINGBOOT - ESPACE LIBRE LE SITE DE LA LICENCE ...

La page est créée Lionel Monnier
 
CONTINUER À LIRE
PREMIER MICRO-SERVICE AVEC LE FRAMEWORK SPRINGBOOT - ESPACE LIBRE LE SITE DE LA LICENCE ...
Premier Micro-service avec
 le FrameWork SpringBoot

                             1
PREMIER MICRO-SERVICE AVEC LE FRAMEWORK SPRINGBOOT - ESPACE LIBRE LE SITE DE LA LICENCE ...
L’architecture micro-services a été inventée pour résoudre certaines des difficultés causées par les gros projets.
Avec le temps, les projets informatiques ont tendance à grossir : on étend petit à petit les fonctionnalités existantes, on en ajoute d’autres, et
on supprime rarement les anciennes.

En même temps que le code et le projet s’étendent, un certain nombre de douleurs apparaissent :
Complexité
Quand la quantité de code augmente, le code devient de plus en plus complexe. Même avec une architecture logicielle solide, les
interdépendances entre les différentes briques augmentent avec le temps.

Cette complexité a deux désavantages :

Évolutivité et fiabilité
• Plus le temps passe, plus les nouvelles fonctionnalités métier deviennent complexes, et plus les différentes briques ont d’interactions. On
   a beau organiser le code en couches et en composants, il y a toujours des cas particuliers et des rustines qui rendent les choses plus
   floues.
• Au-delà d’un certain seuil, il devient impossible d’avoir en tête un modèle global du projet.
• Même avec une base de tests solide, la multiplication des effets de bord de chaque action rend le système moins fiable, et il devient alors
   plus difficile d’ajouter proprement des nouvelles fonctionnalités et d’effectuer des « refactorings ».

« Scalabilité » horizontale
• Améliorer la « scalabilité » d’un système peut demander de modifier des éléments structurants du projet.
• Plus un projet est gros, plus ces interventions deviennent coûteuses et risquées.
• Le risque est alors de se retrouver avec un système qu’il est impossible de faire évoluer pour un nouveau cas d’usage.
                                                                                                                                        2
PREMIER MICRO-SERVICE AVEC LE FRAMEWORK SPRINGBOOT - ESPACE LIBRE LE SITE DE LA LICENCE ...
Innovation
Innovation technologique
• Pour capitaliser les investissements et faciliter la gestion des personnes, il est normal de vouloir avoir une cohérence
   entre les différents projets d’une entreprise : même manière de travailler, mêmes langages de programmation, mêmes
   outils.
• Chaque projet est invité à suivre des choix transverses, et peut s’en écarter en fonction de ses spécificités, à condition de
   le justifier.
• Pour les gros projets, la même tension a lieu à l’intérieur même des projets : pour éviter la fragmentation, chaque
   évolution technique doit pouvoir être propagée à l’intégralité du code.
• Avec le temps, les modifications deviennent donc plus coûteuses, et il est plus difficile d’introduire de nouveaux outils
   pour des besoins spécifiques.

Innovation métier
• Pour répondre aux nouveaux besoins métier, il faut être capable de ménager une zone d’innovation à l’intérieur des
   projets.
• Car si certaines nouveautés sont mises en œuvre par de nouveaux projets, la plupart se font sur des projets existants.
• Or plus un projet est gros, plus il est critique pour l’entreprise, moins on va prendre de risques de le modifier pour tester
   de nouveaux produits ou de nouveaux marchés, et petit à petit les enjeux de stabilité vont prendre le pas sur la capacité
   d’innovation.

                                                                                                                        3
PREMIER MICRO-SERVICE AVEC LE FRAMEWORK SPRINGBOOT - ESPACE LIBRE LE SITE DE LA LICENCE ...
« Le découpage se fait par domaine métier, en groupant les
services et les types de données qui ont des liens forts, et en
séparant quand ils sont suffisamment indépendants. »

                                                                  4
PREMIER MICRO-SERVICE AVEC LE FRAMEWORK SPRINGBOOT - ESPACE LIBRE LE SITE DE LA LICENCE ...
Les avantages de l’approche micro-services
Complexité
Évolutivité et fiabilité

Contraindre la taille limite les cas particuliers, et permet d’avoir en tête l’intégralité des comportements.

La dette technique est gardée sous contrôle, et le code est ainsi capable d’évoluer. Passer par des appels de services pour communiquer avec
les autres domaines formalise les échanges.
Les contrats d’interface sont alors plus carrés, et il est plus facile de prendre en compte tous les cas, y compris les cas d’erreurs.

Scalabilité horizontale

Avec des applications d’une taille limitée, il est plus facile d’augmenter la « scalabilité » en « refactorant » le code ou en la réécrivant
complètement en fonction des nouveaux besoins.

Innovation

Innovation technologique

Les bases de codes et les équipes sont indépendantes et peuvent donc faire leurs choix techniques en fonction de leurs besoins propres.

Innovation métier

Si tout le système d’information est structuré en services, il est facile d’expérimenter en démarrant un nouveau projet s’appuyant sur 5les
données des autres, et plus facile de décomissionner car c’est l’ensemble d’un projet qui sera supprimé.
PREMIER MICRO-SERVICE AVEC LE FRAMEWORK SPRINGBOOT - ESPACE LIBRE LE SITE DE LA LICENCE ...
Parler Micro-Services c’est bien, en faire c’est mieux
Les Micro-Services ont cette fâcheuse tendance à faire parler les gens plutôt qu'à les faire coder.

Il partage d’ailleurs ce biais avec son lointain ancêtre/collègue/SOA.

Il faut dire qu'à l'époque SOA (il y a 5-10 ans donc), il fallait faire avec SOAP, les ESB (EAI « rebrandés »); il valait
mieux en parler qu’en faire.

Mais maintenant tout n’a pas changé mais nous avons enfin les technologies nous permettant de mettre en place
l’ensemble des architectures/solutions rêvées il y a quelques années (Relisez :
http://shop.oreilly.com/product/9780596006754.do ), le livre a plus de 10 ans, si c’est pas du MicroServices, ça y
ressemble.

Plus d’excuse pour ne plus en faire :
Spring Boot est un très bon point d’entrée pour mettre en œuvre
une architecture MicroServices : simplicité, légèreté, éfficacité …​

                                                                                                                            6
PREMIER MICRO-SERVICE AVEC LE FRAMEWORK SPRINGBOOT - ESPACE LIBRE LE SITE DE LA LICENCE ...
L’approche Micro-Services avec SpringBoot

                                            7
PREMIER MICRO-SERVICE AVEC LE FRAMEWORK SPRINGBOOT - ESPACE LIBRE LE SITE DE LA LICENCE ...
Spring Boot est un projet ou un micro framework qui a notamment pour but de faciliter la configuration d’un projet
Spring et de réduire le temps alloué au démarrage d’un projet.

Pour arriver à remplir cet objectif, Spring Boot se base sur plusieurs éléments :

•Une génération rapide de la structure de votre projet en y incluant toutes les dépendances Maven nécessaires à votre
application.

•L’utilisation de « Starters » pour gérer les dépendances.
Spring a regroupé les dépendances Maven de Spring dans des « méga dépendances » afin de faciliter la gestion de celles-
ci.

Par exemple si vous voulez ajouter toutes les dépendances pour gérer la sécurité il suffit d’ajouter le starter « spring-boot-starter-
security ».

                                                                                                                                         8
PREMIER MICRO-SERVICE AVEC LE FRAMEWORK SPRINGBOOT - ESPACE LIBRE LE SITE DE LA LICENCE ...
•L’auto-configuration, qui applique une configuration par défaut au démarrage de votre application pour toutes
dépendances présentes dans celle-ci.

•Cette configuration s’active à partir du moment où vous avez annoté votre application avec
« @EnableAutoConfiguration » ou « @SpringBootApplication ».

•Bien entendu cette configuration peut-être surchargée via des propriétés Spring prédéfinie ou via une configuration Java.

•L’auto-configuration simplifie la configuration sans pour autant vous restreindre dans les fonctionnalités de Spring.

Par exemple, si vous utilisez le starter « spring-boot-starter-security », Spring Boot vous configurera la sécurité dans votre application
avec notamment un utilisateur par défaut et un mot de passe généré aléatoirement au démarrage de votre application.

                                                                                                                                      9
PREMIER MICRO-SERVICE AVEC LE FRAMEWORK SPRINGBOOT - ESPACE LIBRE LE SITE DE LA LICENCE ...
• En plus de ces premiers éléments qui facilitent la configuration d’un projet, Spring Boot offre d’autres avantages
  notamment en termes de déploiement applicatif.

• Habituellement, le déploiement d’une application JEE nécessite la génération d’un fichier .war qui doit être
   déployé sur un serveur comme un Apache Tomcat.
  Spring Boot simplifie ce mécanisme en offrant la possibilité d’intégrer directement un serveur Tomcat dans votre
exécutable. Au lancement de celui-ci, un Tomcat embarqué sera démarré afin de faire fonctionner votre application.

• Enfin, Spring Boot met à disposition des opérationnels, des métriques qu’ils peuvent suivre une fois l’application
  déployée en production. Pour cela Spring Boot utilise « Actuator » qui est un système qui permet de monitorer une
  application via des URLs spécifiques ou des commandes disponibles via SSH « CraSH ». Vous avez toujours la possibilité
  de monitorer également vos services avec JMX.

                                                                                                                 10
• Accélérer le développement d’applications JEE

• Dépendances prêtes à l’emploi

• Auto-Configuration

• StandAlone application

• Déploiement simplifié

• Tomcat/Jetty en mode embarqué.

• Fonctionnalités pour la production.

• Pas de génération de code/de XML

                                                  11
Technologies supportées

Core : Spring Security, JTA, Spring Cache, Spring Session
Web : Spring MVC, WebSocket, Jersey, Mobile, HATEOS
Moteur de templates : Freemaker, Thymeleaf, Groovy, Mustache
Database :
      SGBDR : Spring Data JPA, JDBC, JOOQ, Hibernate
      NoSql : Redis, MongoDB, ElasticSearch, Cassandra
Spring Cloud : Eureka, Hystrix, Turbine, AWS, OAuth2
I/O : Spring Batch et Integration, JavaMail, Camel, JMS, AMQP
Social : Facebook, Linkedln, Twitter

                                                                 12
13
Prérequis indispensable
 Installer le jdk 8 dans sa dernière version (Fonctionne également avec le JDK 11)
      http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

                                                        La U202 est la dernière version du JDK8 qui sera disponible
                                                        en patch libre les prochaines versions seront payante, il est
                                                        donc conseillé de passer au JDK 11 avec les restrictions de
                                                        la licence commerciale ou la version Open Source sous
                                                        licence GPL

                                                                                       https://jdk.java.net/11/

 Penser à définir la variable JAVA_HOME correctement,
 Ainsi que votre PATH

 echo %JAVA_HOME%         OR echo $JAVA_HOME
 echo    %PATH% OR echo $PATH
                                                                                                             14
Prérequis +/- indispensable
Installer NetBeans 8.2 pour JEE                                 https://netbeans.org/downloads/
Essentiellement pour la prise en charge du HTML et JavaScript

                                                                                                  15
Prérequis +/- indispensable
    Installer le plugin NetBeans pour SpringBoot Ce plugins propose la création d’un projet Maven Spring Boot simplifié)
                              NB Spring Boot version 1.5

                                                                                                              16
Prérequis indispensable
   installer Maven version 3.5.0

                       https://maven.apache.org/download.cgi

    Ajouter le chemin
    C:\apache-maven-3.5.0-bin\apache-maven-3.5.0\bin
    Dans la variable PATH
    Tester l’installation et la version

                                                               17
Backend MicroService via WS REST et AMQP
                                          3
                                    Microservice
                                   Avec persistence
                                    Des données

              Front     WS-REST      Microservice     WS-REST   Microservice
            Browser                  MiddleWare                   Backend
            Internet         1       Dispatcher             2   REST Service

                                   Message amqp

                                  Bus AMQP RabbitMQ

                                   Message amqp

                                    Service Backend
                                         AMQP
                             1      Consommateur

                                                                               18
Créer un premier package Maven Basic SpringBoot          1

Sous NetBeans :
File | New Project | Maven | Spring Boot basic project

                                                             19
1   Refactorisation du projet :
    Nom du projet(1) , chemin du package(2), nom du fichier principal Java (3)
    (Clic droit + renommer ou clic droit + Refactor + Renommer)

    Re-factoriser le package de test également
    Chemin du package de test (4) , nom du fichier principal Java de test (5)

                                                                                 20
Créer un premier package Maven SpringBoot Initializr
Sous NetBeans :
File | New Project | Maven | Spring Boot Initializr project

                                                              21
Vous pouvez également créer votre projet via le site Spring InitialiZr

           https://start.spring.io/

                                                                         22
1
    Ajouter les dépendances complémentaires au projet (spring-boot-starter-web)
    Clic droit sur « dependencies » de notre projet

                                                      Ajouter la dépendance spring-boot-starter-web

                                                                                                      23
1
    Ajouter la dépendance amqp RabbitMQ client amqp-client

                                                             24
1   Accéder au fichier pom.xml sous NetBeans
Vous accédez au fichier pom via le menu contextuel sur la zone de projet NetBeans, menu « Open POM »

                                          Ce qui vous permet d’accéder en écriture sur le fichier POM et de
                                          corriger les informations de votre projet comme ci-dessous par
                                          exemple

                                           com.ht.dev

                                          PremierMicroService
                                              0.0.1
                                              jar

                                              PremierMicroService
                                              Basic project for Spring
                                          Boot

                                                                                                              25
Exemple de code source qui permet de mettre en place 3 web services REST et un Producteur pour rabbitMQ.   1
package com.ht.dev;

import   com.rabbitmq.client.Channel;
import   com.rabbitmq.client.Connection;
import   com.rabbitmq.client.ConnectionFactory;
import   java.io.IOException;
import   java.util.concurrent.TimeoutException;
import   org.springframework.boot.SpringApplication;
import   org.springframework.boot.SpringBootConfiguration;
import   org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import   org.springframework.stereotype.Controller;
import   org.springframework.web.bind.annotation.PathVariable;
import   org.springframework.web.bind.annotation.RequestMapping;
import   org.springframework.web.bind.annotation.RequestMethod;
import   org.springframework.web.bind.annotation.ResponseBody;

//@SpringBootApplication
@Controller
@EnableAutoConfiguration
@SpringBootConfiguration
public class PremierMicroService {

         public static void main(String[] args) {
                SpringApplication.run(PremierMicroService.class, args);
         }                                                                                                 26
@RequestMapping("/hello")       1
   @ResponseBody
   String home() {
       return "Salut les licences 3 alt!";
   }

  @RequestMapping("/message")
  @ResponseBody
  String message() throws TimeoutException {
       String QUEUE_NAME = "hello";
       ConnectionFactory factory = new ConnectionFactory();
       factory.setHost("localhost");
       String message = "Salut les licences 3 alt!";
       try
       {
         Connection connection = factory.newConnection();
         Channel channel = connection.createChannel();
         channel.queueDeclare(QUEUE_NAME, false, false, false, null);
         channel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8"));
         channel.close();
       }
    catch (IOException ex) {
         return ex.getMessage();
     }
       return " [x] Envoyé '" + message + "'";
  }
                                                                                  27
@RequestMapping(value="/message/{msg}", method=RequestMethod.GET)     1
   @ResponseBody
   String messageMsg(@PathVariable("msg") String msg) throws TimeoutException {
       String QUEUE_NAME = "hello";
       ConnectionFactory factory = new ConnectionFactory();
       factory.setHost("localhost");
       try
       {
         Connection connection = factory.newConnection();
         Channel channel = connection.createChannel();

            channel.queueDeclare(QUEUE_NAME, false, false, false, null);
            channel.basicPublish("", QUEUE_NAME, null, msg.getBytes("UTF-8"));
            System.out.println();

            channel.close();
          }
       catch (IOException ex) {
            return ex.getMessage();
        }
          return " [x] Envoyé '" + msg + "'";
   }

} //fin de programme

                                                                                  28
désactiver "Compile on Save" avant de compiler et exécuter le projet sous NetBeans
Clic droit sur le projet, puis menu « Properties »

                                                                                     29
cmd /c "\"\"C:\\Program Files\\NetBeans 8.2\\java\\maven\\bin\\mvn.bat\" -Drun.jvmArguments=\"-noverify -XX:TieredStopAtLevel=1 -Xms64m\" -
                                 Drun.mainClass=com.example.BasicApplication -Dmaven.ext.class.path=\"C:\\Program Files\\NetBeans 8.2\\java\\maven-nblib\\netbeans-eventspy.jar\" -Dfile.encoding=UTF-8
                                 spring-boot:run\""
                                 Scanning for projects...

Tester notre MicroService        ------------------------------------------------------------------------
                                 Building PremierMicroService 0.0.1-SNAPSHOT
                                 ------------------------------------------------------------------------

Lancer le projet sous NetBeans   >>> spring-boot-maven-plugin:1.5.2.RELEASE:run (default-cli) @ basic >>>

                                 --- maven-resources-plugin:2.6:resources (default-resources) @ basic ---
                                 Using 'UTF-8' encoding to copy filtered resources.
                                 Copying 1 resource
                                 Copying 0 resource

                                 --- maven-compiler-plugin:3.1:compile (default-compile) @ basic ---
                                 Nothing to compile - all classes are up to date

                                 --- maven-resources-plugin:2.6:testResources (default-testResources) @ basic ---
                                 Using 'UTF-8' encoding to copy filtered resources.
                                 skip non existing resourceDirectory C:\TEMP\PremierMicroservice\src\test\resources

                                 --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ basic ---
                                 Nothing to compile - all classes are up to date
Tester les web service avec un browser
http://localhost:8080/hello
http://localhost:8080/message
http://localhost:8080/message/Bonjour le monde du microservice

                                                                 31
Compiler et packager avec Maven

Se rendre dans le dossier du projet ou se trouve le fichier pom.xml et lancer la commande Maven :
mvn package
Se rendre ensuite dans le dossier Target ou a été généré notre package Jar

                                                                                                    32
Lancer le microService avec la commande Maven
mvn spring-boot:run
OU JAVA
java –jar basic-0.0.1-SNAPSHOT.jar

                                                33
Exécution du consommateur

                            34
Backend MicroService via WS REST et AMQP
                                          3
                                    Microservice
                                   Avec persistence
                                    Des données

              Front     WS-REST      Microservice     WS-REST   Microservice
            Browser                  MiddleWare                   Backend
            Internet         1       Dispatcher             2   REST Service

                                   Message amqp

                                  Bus AMQP RabbitMQ

                                   Message amqp

                                    Service Backend
                                         AMQP
                             1      Consommateur

                                                                               35
1 Ajouter un appel supplémentaire de Web service (au service Backend) à notre projet PremierMicroService
 public class PremierMicroService {

      private RestTemplate template=new RestTemplate();

      //mapper dans le fichier application.properties
      @Value("${backend.backendServiceHost}")
      String backendServiceHost;
      @Value("${backend.backendServicePort}")
      int backendServicePort;

     @RequestMapping(value="/backend", method=RequestMethod.GET, produces="text/plain")
     @ResponseBody
     String CallBackend() {
         //construire et appeler le service Backend
         String backendServiceURL=String.format("http://%s:%d/backend",
 backendServiceHost, backendServicePort);

           BackendDTO reponse=template.getForObject(backendServiceURL, BackendDTO.class);

           //return backendServiceURL;
           return reponse.getReponse();
      }

                                                                                                           36
1   Classe POJO BackEndDTO                        Placer les paramètre du WS dans le fichier
                                                  Application.properties

           package com.ht.dev;                       management.security.enabled=false
                                                     backend.backendServiceHost=localhost
           public class BackEndDTO {                 backend.backendServicePort=8081
               String reponse;

                public String getReponse() {
                    return reponse;
                }

                public void setReponse(String reponse) {
                    this.reponse = reponse;
                }

           }

                                                                                          37
2   Création du service Backend BackendMicroService

package com.ht.dev;

import   org.springframework.boot.SpringApplication;
import   org.springframework.boot.autoconfigure.SpringBootApplication;
import   org.springframework.stereotype.Controller;
import   org.springframework.web.bind.annotation.RequestMapping;
import   org.springframework.web.bind.annotation.RequestMethod;
import   org.springframework.web.bind.annotation.ResponseBody;

@SpringBootApplication
@Controller
public class BackendMicroService {

    @RequestMapping(value="/backend", method=RequestMethod.GET, produces="application/json")
       @ResponseBody
    public Reponse backendReponse(){
        return new Reponse(String.format("Bonjour de la part du Backend"));
    }

         public static void main(String[] args) {
                SpringApplication.run(BackendMicroService.class, args);
         }
}                                                                                       38
2   La classe Reponse.java (Un pojo d’encapsulation permettant de générer la réponse en Json(par défaut))

                    package com.ht.dev;

                    class Reponse{
                     String reponse;

                         public String getReponse() {
                             return reponse;
                         }

                         public Reponse(String format) {
                           reponse=format;
                         }
                    }

                                                                                                            39
2
    Avant de lancer le microService BackendMicroService, ne pas oublier de spécifier le port 8081 pour le
    démarrage de ce service.
    On va spécifier cette valeur de port dans le fichier application.properties

                                      server.port=8081

                                                                                                            40
Monitorer vos microServices avec JMX
Par défaut Spring Boot active les objets JMX dans son code, ce qui permet de monitorer vos microservices avec
l’outils « Java Mission Control » jmc.exe qui se trouve dans le bin du JDK.

                                                                                                                41
Monitorer vos microServices avec Spring Boot Starter Actuator 1.5.3
      Insérer la dépendance suivant dans votre projet, ceci permet d’ajouter des Web Services à votre application
                                             Placer dans le fichier de config application.properties
org.springframework.boot              management.security.enabled=false
spring-boot-starter-actuator
1.5.3.RELEASE

                                           Example : le EndPoint http://localhost:8080/env ressemblera à :

    • http://localhost:8080/beans
    • http://localhost:8080/env
    • http://localhost:8080/health
    • http://localhost:8080/metrics
    • http://localhost:8080/trace
    • http://localhost:8080/mappings
                                                                                                                    42
Codecentric a développé une UI intéressante que l’on peut cloner à partir de GitHub.

              https://github.com/codecentric/spring-boot-admin

                                                                                       43
Backend MicroService via WS REST et AMQP
                                          3
                                    Microservice
                                   Avec persistence
                                    Des données

              Front     WS-REST      Microservice     WS-REST   Microservice
            Browser                  MiddleWare                   Backend
            Internet         1       Dispatcher             2   REST Service

                                   Message amqp

                                  Bus AMQP RabbitMQ

                                   Message amqp

                                    Service Backend
                                         AMQP
                             1      Consommateur

                                                                               44
package com.ht.dev;
                                                                                                  3      Couche Persistance avec JDBCTemplate
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
                                                                                                 Créer un nouveau projet et ajouter les
import org.springframework.beans.factory.annotation.Autowired;                                   Dépendance ci-dessous
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@SpringBootApplication
@Controller
public class BackendJDBCMicroService implements CommandLineRunner{

  private static final Logger log = LoggerFactory.getLogger(BackendJDBCMicroService.class);

  @Autowired
  JdbcTemplate jdbcTemplate;

  @RequestMapping("/name/{NOM}/fname/{PRENOM}")
  @ResponseBody
  public String Insert_Person(@PathVariable("NOM") String nom, @PathVariable("PRENOM") String prenom){
    jdbcTemplate.update("INSERT INTO APP.persons(first_name, last_name) VALUES (?,?)", nom, prenom);
    return "Insertion "+nom+" "+prenom+" ok";
  }                                                                                                                                 45
3

    @Override
    public void run(String... strings) {

        log.info("Creation de la table");

        try {
        //jdbcTemplate.execute("DROP TABLE persons");
        jdbcTemplate.execute("CREATE TABLE APP.persons(id INTEGER, first_name VARCHAR(255), last_name VARCHAR(255))");
        }
        catch(DataAccessException e) {}
    }

             public static void main(String[] args) {
                       SpringApplication.run(BackendJDBCMicroService.class, args);
             }
}

                                                                                                             46
3   Classe qui va servir de rowMapper lors des Query

package com.ht.dev;

public class Person {

    private long id;
    private String firstName, lastName;

    public Person(long id, String firstName, String lastName) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return String.format(
                "Person[id=%d, firstName='%s', lastName='%s']",id, firstName,
lastName);
    }

}

                                                                                           47
Avant de lancer le microService BackendJDBCMicroService, ne pas oublier de spécifier les données d’accés à la
 base de données Java Derby embedded.
 On va spécifier ces valeurs dans le fichier application.properties

spring.datasource.driver-class-name=org.apache.derby.jdbc.EmbeddedDriver
spring.datasource.url=jdbc:derby:backendJDBCMicroService;create=true
spring.datasource.username=bjms
spring.datasource.password=bjms

                                                                                                             48
3   Requêter dans la base de données

List persons = new ArrayList();

        List rows=jdbcTemplate.queryForList("SELECT * FROM APP.persons WHERE
last_name='TONDEUR'");

        for (Map rs : rows) {
               Person personne = new Person((Long)rs.get("id"), (String)rs.get("first_name"),
(String)rs.get("last_name"));
               persons.add(personne);
       }

                                                                                         49
Exemple d’une réponse HTTP et d’un corps au format JSON

@RequestMapping(value="/arnum/{cle}/IPP={IPP}",method = RequestMethod.GET)
private ResponseEntity getByName(@PathVariable("cle") String cle,@PathVariable(« IPP") String
IPP)
    {

        List patients=new ArrayList();

        List rows =jdbcTemplate.queryForList(sql);
        rows.forEach((row) -> {
            Patient p=new Patient();
            p.setIPP("12345");
                 …
                patients.add(p);
          });

        //si la liste est vide
        if (patients.isEmpty()) {
            return new ResponseEntity(HttpStatus.NO_CONTENT); //pour être RESTfull}
        //sinon on retourne la liste
        return new ResponseEntity(patients, HttpStatus.OK); //et le status 200 OK
    }

                                                                                                       50
Notions MVC avec Spring Boot

Toutes les pages statiques doivent se trouver dans le dossier ./static
Il est nécessaire d’inserer une dépendance Web et ThymeLeaf pour réaliser l’appel d’un Template de vue.
Les Templates de vue seront développé sous ThymeLeaf de préférence.
On place les Template dans le dossier ./template du projet.

Chaque projet développé en MVC, doit principalement présenter une classe Controller (dispatcher), une ou des
classes métiers pour les accès aux ressources, et des Template écrit en HTML et ThymeLeaf.

On utilisera la classe Model qui permettra de faire la liaison entre notre controller et les Template.

                                                                                                               51
package com.ht.dev.testms;

import   org.springframework.boot.SpringApplication;
import   org.springframework.boot.autoconfigure.SpringBootApplication;
import   org.springframework.context.annotation.ComponentScan;              Déclaration d’une application SpringBoot
import   org.springframework.stereotype.Controller;
import   org.springframework.ui.Model;
import   org.springframework.web.bind.annotation.RequestMapping;
import   org.springframework.web.bind.annotation.RequestMethod;
import   org.springframework.web.bind.annotation.RequestParam;
                                                                                           Dispatcher de l’appel de la
@SpringBootApplication                                                                     page Web ./bonjour en type
@Controller                           Déclaration de la classe controller                  POST
@ComponentScan
public class TestMsApplication {

       @RequestMapping (value="/bonjour",method=RequestMethod.POST)
    private String bonjour(@RequestParam(name="nom", required=false, defaultValue="Hervé") String nom,
Model model)
    {
        model.addAttribute("nom", nom); Utilisation de la classe Model pour l’appel
        return "bonjour";                                                               Mapping de la variable
    }                                    du Template HTML « bonjour.html »
                                                                                                nom transmis par le
          public static void main(String[] args) {                                              protocole POST avec la
                   SpringApplication.run(TestMsApplication.class, args);                        variable locale nom
          }
}
                                                                                                              52
Exemple de Template ThymeLeaf (page bonjour.html)

 Voir documentation ThymeLeaf :
 http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html
 http://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html

        Page Bonjour
        
                                                                             53
Discovery Service : Eureka
 dans une architecture AMS, le focus doit être fait non seulement sur le découpage des services mais aussi
et surtout sur les interactions entre ces services.
Il sera nécessaire d’éviter d'appeler un service directement via sa localisation (même si elle est configurée selon la
plateforme cible de déploiement).
Par exemple, évitez d'utiliser l'url: http[s]://[host]:[port]/[nameservice] afin de ne pas créer un couplage
fort entre les services.
On mettra donc en place dans notre MS un service de Discovery.

On distinguera le "Server-Side Discovery" du "Client-Side Discovery".

Pour en savoir plus sur la notion de "Service Discovery" voir :
https://www.todaysoftmag.com/article/1429/micro-service-discovery-using-netflix-eureka

C’est le client qui s'enregistre dans le "Service Discovery". L'inconvénient de cette approche est de coder cette
partie dans chaque service client. Mais avec l'API Spring la tâche est plus simple.

                                                                                                                  54
55
Discovery Service Exemple
                                                   Serveur NetFlix
                                                       Eureka
                                                      discovery

                                        2

                                                  1               1

                                 Microservice         Use WS-REST         Microservice
                                  FrontEnd                                  Backend
                                 Dispatcher                 3             REST Service

                   3    (1) Nos services Backend Et FrontEnd vont s’enregistrer auprès du service
  Front                     NetFlix Eureka discovery.
Browser                 (2) Notre service FrontEnd va interroger le service Discovery pour connaitre
Internet                    le Host et le port du service BackEnd lors de l’appel WS (3) provenant du
                            client via le service FrontEnd.
                                                                                                  56
Service Discovery Registry (server side)
https://github.com/univphf/ServerDiscovery.git
•Créer     un     projet   spring-boot      afin     de     centraliser   et     d'enregistrer      les         services,
La solution open-source, Eureka, de Netflix et l'API Spring-Cloud rendront cette entreprise facile.

•Compléter ou vérifier le pom projet

•Annoter la classe générée par spring-boot

•Configurer le service Eureka Registry.

  Créer un nouveau projet SpringInitializr et insérer la dépendance Maven « Eureka discovery » et « Eureka Server »
  
         org.springframework.cloud
         spring-cloud-starter-eureka
  
         org.springframework.cloud
         spring-cloud-starter-eureka-server
         1.3.0.RELEASE
  
                                                                                                                  57
La classe DemoApplication est générée et annotée avec @SpringBootApplication de Spring-Boot, nous
   l'annotons également avec @EnableEurekaServer de spring-cloud
   (package org.springframework.cloud.netflix.eureka.server.EnableEurekaServer).

   Faisant cela, nous avons utilisé la brique de Netflix nommée Eureka qui est un "service discovery ou
   service registry".

   L'annotation @EnableEurekaServer est "side server", fournie par l'api spring-cloud pour faciliter la mise
   en place de la découverte du service Eureka.

 Fichier : application.properties du projet
server.port=8761
eureka.instance.hostname=localhost
eureka.client.fetchRegistry=false
eureka.client.registerWithEureka=false
logging.level.com.netflix.eureka=OFF
logging.level.com.netflix.discovery=OFF
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
eureka.environment=prod
eureka.datacenter=HTMain

                                                                                                          58
Tester le service Eureka
Il suffit d'exécuter le projet mvn clean package spring-boot:run puis de saisir dans le browser
l'url localhost:8761 pour voir s'afficher la page du service Eureka.

  A ce stade aucune instance de micro-service n'est enregistrée d'où la mention "No instances available".

                                                                                                       59
https://github.com/univphf/ClientDiscovery.git

Service Discovery Client (client side)
•Créer un second projet spring-boot définissant le micro-service qui sera déployé dans le serveur
Eureka.

•Compléter ou vérifier le pom projet,

•Annoter la classe générée par spring-boot,

•Ecrire un RestController pour illustrer les notions de consommation de services via leurs noms
enregistrés dans "Eureka Registry".

                                                                                               60
Créer un nouveau projet SpringInitializr et insérer la dépendance Maven « Eureka discovery »

           org.springframework.cloud
           spring-cloud-starter-eureka
    
 Annoter la classe générée
 La classe générée par spring-boot va être annotée avec @EnableEurekaClient de l'API spring-cloud pour
 Netflix comme suit :

L'annotation @EnableEurekaClient va garantir que le service s'enregistre automatiquement dans le registry
eureka. C'est aussi simple que cela! Juste une annotation apposée sur la classe main générée. L'étape
suivante va permettre de compléter la configuration utile pour l'auto-enregistrement dans le service discovery
eureka.

                                                                                                          61
Configurer le Client BackEnd Eureka

Fichier : application.properties du projet

spring.application.name=back
server.port=8081
eureka.client.fetchRegistry=true
eureka.client.registerWithEureka=true
eureka.client.useDnsForFetchingServiceUrls=false
instance.metadataMap.instanceId=${spring.application.name}:${server.port}

                                                                            62
Controller Rest de l’application BackEnd          https://github.com/univphf/ClientBackDiscovery.git
package com.dev.ht.clientbackdiscovery;

import   org.springframework.boot.SpringApplication;
import   org.springframework.boot.autoconfigure.SpringBootApplication;
import   org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import   org.springframework.web.bind.annotation.RequestMapping;
import   org.springframework.web.bind.annotation.ResponseBody;
import   org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
@EnableEurekaClient

public class ClientbackdiscoveryApplication {

      @RequestMapping({"/info","/"})
                                                                                 Mise à disposition d’un service
      String info(){return ="Je suis la pages d'infos du back service";}                info pour Eureka

     @RequestMapping({"/bonjour"})
     @ResponseBody
     String bonjour(){return "Bonjour tout le monde!";}

          public static void main(String[] args) {
                   SpringApplication.run(ClientbackdiscoveryApplication.class, args);
          }
}

                                                                                                            63
Configurer le Client FrontEnd Eureka

                https://github.com/univphf/ClientFrontDiscovery.git

Fichier : application.properties du projet (autre paramètres possibles)

    spring.application.name=front
    server.port=8090
    eureka.client.fetchRegistry=true
    eureka.client.registerWithEureka=true
    eureka.client.useDnsForFetchingServiceUrls=false
    eureka.client.eurekaServerDNSName=localhost
    eureka.client.eurekaServerPort=8761
    eureka.client.eurekaServerURLContext=eureka
    instance.metadataMap.instanceId=${spring.application.name}:${server.port}

                                                                                64
Controller Rest de l’application FrontEnd qui pourra appeler les services BackEnd
                                                                     package com.dev.ht.clientfrontdiscovery;
@SpringBootApplication
@RestController                                                      import   java.util.List;
@EnableEurekaClient                                                  import   org.springframework.cloud.client.discovery.DiscoveryClient;
                                                                     import   org.springframework.beans.factory.annotation.Autowired;
public class ClientfrontdiscoveryApplication {                       import   org.springframework.boot.SpringApplication;
                                                                     import   org.springframework.boot.autoconfigure.SpringBootApplication;
    @Autowired                                                       import   org.springframework.cloud.client.ServiceInstance;
    private DiscoveryClient discoveryClient;                         import   org.springframework.web.bind.annotation.RequestMapping;
                                                                     import   org.springframework.web.bind.annotation.RestController;
    public String serviceUrl() {
        final StringBuilder sb=new StringBuilder();
         List instance = discoveryClient.getInstances("back");
                instance.forEach(
                                 si ->
                                  {
                               sb.append ("Host= ");
                              sb.append(si.getHost());
                              sb.append(" Uri= ");
                              sb.append(si.getUri());
                              sb.append(" Port= ");
                              sb.append(si.getPort());                                }
                               );
        System.out.println("sb= "+sb.toString());

        return "taille : "+instance.size();
    }

    @RequestMapping("/discover")
    public String index() {return serviceUrl();}

    public static void main(String[] args) {
                    SpringApplication.run(ClientfrontdiscoveryApplication.class, args);
          }                                                                                                                    65
}
Permet d’appeler le service REST /info de notre
                 application

                                                  66
Circuit breaker, un pattern pour fiabiliser vos microservices (ou systèmes distribués)

 Les “Illusions de l’informatique distribuée” nous mène a se poser les questions :

 Le réseau est fiable.
 Le temps de latence est nul.
 La bande passante est infinie.
 Le réseau est sûr.
 La topologie du réseau ne change pas.
 Il y a un et un seul administrateur réseau.
 Le coût de transport est nul.
 Le réseau est homogène.
 Et ces illusions ne prennent pas en compte la partie dépendance et leurs lots de problèmes (crash, temps de réponse lent,
 réponse non conforme…).

 Pour répondre à ces défis, la philosophie de « design for failure » (les traitements applicatifs doivent, dès leur conception,
 prévoir le cas où les composants qu’ils appellent pourraient tomber en erreur) a pris encore plus d’importance.

                                                                                                                          67
Les solutions
 lift and shift Il suffit de prendre son application telle quelle et de la mettre sur le cloud sans faire de
                modification (technique du lift and shift) => Utilisation de services en haute disponibilité & Utilisation
                d’une infrastructure moderne => Cela n’est pas suffisant si l’application ne supporte pas la charge ou mal
                développé (IP en fixe par exemple), le cloud peut couter cher également.

Utilisation de répartiteur de charge Utilisation de HAProxy par exemple (répartiteurs de
                                     requêtes)=> Impossibilité d’ajout de répartiteur de
                                     charge dans certains cas (service externe, protocole
                                     non supporté, stockage des données) =>
                                     Complexification de l’architecture et donc de
                                     l’exploitation et du diagnostic des problèmes de
                                     production => Complexité de trouver la bonne
                                     configuration pour les lignes de vie (health check)

                                                                                                                  68
Design pattern : Timeout       Il permet de ne pas attendre indéfiniment une
                                réponse en positionnant un temps d’attente
                                maximal=> L’erreur n’arrivera qu’après le temps
                                d’attente maximum (contraire au fail fast)=>
                                Consommation de ressource (connexion,
                                mémoire) inutile

Design pattern : Retry Pattern Il consiste à envoyer à nouveau la requête qui a
                               échoué. Et donc si le service appelé “tombe en
                               marche”, cela sera transparent pour l’utilisateur
                               au prix d’une latence significative=>Si le service
                               appelé reste hors service, un risque de surcharge de
                               l’application en multipliant les requêtes

                                                                                      69
Circuit Breaker

Le circuit breaker permet de contrôler la collaboration entre différents services afin d’offrir une grande tolérance à la latence
et à l’échec en fonction d’un certain nombre de critères d’erreur (timeout, nombre d’erreurs, élément dans la réponse), ce
pattern permet de désactiver l’envoi de requêtes au service appelé et de renvoyer plus rapidement une réponse alternative
de repli (fallback), aussi appelé graceful degradation.
Il agit comme un proxy implémentant une machine à états (Ouvert, Passant (fermé), Semi-ouvert) pour l’apprentissage de
l’état du service.

                                                                                                                       70
Lorsque le nombre d’échecs successifs dépasse un seuil, le circuit s’ouvre pour
 ne plus laisser passer de requêtes. À ce moment-là, deux mécanismes se
déclenchent :

Mise en place de la réponse alternative de repli

Activation du processus du passage à l’état semi-ouvert (Déclenchement d'un minuteur).

Une fois le seuil de passage à l’état semi-ouvert atteint (seuil du temps d’attente), le circuit breaker laisse à nouveau passer
quelques requêtes et passe dans l’état passant si tout se déroule bien.

Nous pouvons envisager une infinité de possibilités :

Stocker toutes les requêtes en erreur avec le maximum de détail pour les traiter plus tard (AMQP / BDD)
Avoir plusieurs stratégies de réponse alternative en fonction du type d’erreur renvoyé par le service appelé (code “HTTP 503
Service Unavailable”, mauvaise réponse…)
Avoir des seuils intelligents qui s’adaptent après une période d’apprentissage
                                                                                                                           71
Graceful degradation

Adaptation automatique de l’application à une situation dégradée.

Exemple : mise en indisponibilité du service, ou affichage d’une réponse alternative.

But => Ne pas afficher de stackTrace à l’utilisateur.

                                                                                        72
Hystrix

https://github.com/Netflix/hystrix/wiki

Hystrix est une API open source développée par Netflix qui implémente le pattern circuit
breaker.

Le but d’Hystrix est de rendre une application résiliente aux pannes de ses dépendances
externes en arrêtant momentanément de les invoquer le temps de leur indisponibilité. On
dit alors que Hystrix ouvre le circuit.

Comme Hystrix n’est pas averti de la reprise d’une dépendance tombée, il tente, à
intervalles réguliers, d’appeler cette dépendance.

Dès que cette dernière est rétablie, il ferme alors son circuit et tous les appels qu’il reçoit
sont transmis à cette dépendance.
                                                                                            73
Hystrix constitue un point d’accès unique à une dépendance externe. Il englobe (wrappe) les appels clients dans un objet
suivant le pattern Command. Concrètement, chaque appel distant est wrappé dans un objet HystrixCommand.
Hystrix fonctionne avec deux modes, thread et sémaphore :

Thread : Hystrix maintient son propre pool de threads. Un appel distant est exécuté par un thread Hystrix. Une fois que
tous les threads sont pris, les nouveaux appels arrivants sont rejetés.

Sémaphore : l’appel distant est exécuté par le même thread du client appelant. Une fois que le nombre de sémaphores
défini est atteint, tous les appels client sont rejetés. Ce mode est préconisé pour les appels courts.

Le mode thread est le mode par défaut d’Hystrix. Il tire son avantage par son isolation du pool de threads de l’appelant.

                                                                                                                    74
CHANGEMENT DE VITESSE

                        75
Les Microservices
ÉLASTIQUE
Un Microservice doit pouvoir être déployé un nombre de fois qui varie en fonction de la demande, et ce,
indépendamment des autres services dans la même application.
RÉSILENT
Un Microservice doit échouer sans affecter d'autres services dans la même application.

                                                         Pourquoi utilise-t-on Docker ?

                                                         Distribution des applications facilitée.
                                                         Comportement identique des applications en
                                                         Dev/Qualif/Prod.
                                                         Déploiement, lancement et arrêt rapide.
                                                         Linux et Windows (en preview dans Windows Server 2016)
                                                         Permet de reconstruire un container à partir d'un simple
                                                         fichier Dockerfiles.
                                                         Gestion des containers avec peu d'outils, identique sur
                                                         toutes les plateformes.
                                                         Des API disponibles pour piloter l'ensemble depuis d'autres
                                                         applications.

                                                                                                            76
SOLUTIONS D'ORCHESTRATION OPENSOURCE

    Docker Machine/Compose/Swarm http://www.docker.com
    Kubernetes http://k8s.io
    Apache Mesos http://mesos.apache.org/
    Openshift Origin v3 http://www.openshift.org
    Rancher http://rancher.com
    Kontena http://www.kontena.io/

                                                          77
Vous pouvez aussi lire