Introduction à Spring Cloud Netflix - Eureka

Introduction à Spring Cloud Netflix - Eureka

1. Vue d'ensemble

Dans ce didacticiel, nous allons présenter la découverte declient-side service via «Spring Cloud Netflix Eureka».

Client-side service discovery allows services to find and communicate with each other without hard-coding hostname and port. Le seul «point fixe» dans une telle architecture est constitué d'unservice registry auprès duquel chaque service doit s'enregistrer.

Un inconvénient est que tous les clients doivent implémenter une certaine logique pour interagir avec ce point fixe. Cela suppose un aller-retour réseau supplémentaire avant la demande réelle.

Avec Netflix Eureka, chaque client peut agir simultanément en tant que serveur pour répliquer son statut sur un homologue connecté. En d'autres termes, un client récupère une liste de tous les homologues connectés d'unservice registry et fait toutes les demandes supplémentaires à tous les autres services via un algorithme d'équilibrage de charge.

Pour être informé de la présence d'un client, il doit envoyer un signal de pulsation au registre.

Pour atteindre l'objectif de cet article, nous allons mettre en œuvre troismicroservices:

  • unservice registry (Eureka Server),

  • un serviceREST qui s'enregistre au registre (Eureka Client) et

  • une application Web, qui consomme le serviceREST en tant que client prenant en charge le registre (Spring Cloud Netflix *Feign Client*).

    == Lectures complémentaires:

Guide sur le cloud printanier Netflix - Hystrix

Cet article explique comment configurer une solution de secours dans la logique de votre application, à l'aide de Spring Cloud Hystrix.

Read more

Spring REST avec un proxy Zuul

Explorer l'utilisation du proxy Zuul pour une API Spring REST, en travaillant autour de CORS et de la contrainte de politique de même origine du navigateur.

Read more

2. Serveur Eureka

L'implémentation d'unEureka Server pour le registre de service est aussi simple que:

  1. ajout despring-cloud-starter-netflix-eureka-server aux dépendances

  2. activer le serveur Eureka dans un@SpringBootApplication en l'annotant avec@EnableEurekaServer

  3. configurer certaines propriétés

Mais nous le ferons étape par étape.

Tout d'abord, nous allons créer un nouveau projet Maven et y placer les dépendances. Vous devez noter que nous importons lesspring-cloud-starter-parent dans tous les projets décrits dans ce didacticiel:


    org.springframework.cloud
    spring-cloud-starter-netflix-eureka-server



    
        
            org.springframework.cloud
            spring-cloud-starter-parent
            Greenwich.RELEASE
            pom
            import
        
    

Remarque: nous pouvons consulter les dernières versions de Spring Cloud dansthe Spring’s Projects documentation.

Ensuite, nous créons la classe d'application principale:

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

Enfin, nous configurons les propriétés au formatYAML; donc unapplication.yml sera notre fichier de configuration:

server:
  port: 8761
eureka:
  client:
    registerWithEureka: false
    fetchRegistry: false

Here we’re configuring an application port – 8761 is the default one for Eureka servers. Nous disons auxEureka Client intégrés de ne pas s'enregistrer avec «lui-même» car notre application devrait agir comme un serveur.

Nous allons maintenant pointer notre navigateur vershttp://localhost:8761 pour afficher le tableau de bord deEureka, où nous inspecterons plus tard les instances enregistrées.

Pour le moment, nous voyons des indicateurs de base tels que les indicateurs de statut et de santé.

image

3. Client Eureka

Pour qu'un@SpringBootApplication soit sensible à la découverte, nous devons inclure certainsSpring Discovery Client (par exemplespring-cloud-starter-netflix-eureka-client) dans nosclasspath.

Ensuite, nous devons annoter un@Configuration avec soit@EnableDiscoveryClient soit@EnableEurekaClient – notez que cette annotation est facultative si nous avons la dépendancespring-cloud-starter-netflix-eureka-client sur le chemin de classe.

Ce dernier indique àSpring Boot d'utiliser explicitement Spring Netflix Eureka pour la découverte de services. Pour remplir notre application cliente avec un exemple de durée de vie, nous allons également inclure le packagespring-boot-starter-web dans lepom.xml et implémenter un contrôleurREST.

Mais d'abord, nous allons ajouter les dépendances. Encore une fois, nous pouvons laisser à laspring-cloud-starter-parent dépendance le soin de déterminer les versions des artefacts pour nous:


    org.springframework.cloud
    spring-cloud-starter-netflix-eureka-starter


    org.springframework.boot
    spring-boot-starter-web

Ici, nous allons implémenter la classe d'application principale:

@SpringBootApplication
@RestController
public class EurekaClientApplication implements GreetingController {

    @Autowired
    @Lazy
    private EurekaClient eurekaClient;

    @Value("${spring.application.name}")
    private String appName;

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

    @Override
    public String greeting() {
        return String.format(
          "Hello from '%s'!", eurekaClient.getApplication(appName).getName());
    }
}

Et l'interfaceGreetingController:

public interface GreetingController {
    @RequestMapping("/greeting")
    String greeting();
}

Ici, au lieu de l'interface, nous pourrions aussi simplement déclarer le mappage à l'intérieur de la classeEurekaClientApplication. L'interface peut être utile si nous voulons la partager entre le serveur et le client.

Ensuite, nous devons configurer unapplication.yml avec un nom d'applicationSpring configuré pour identifier de manière unique notre client dans la liste des applications enregistrées.

Nous pouvons laisserSpring Boot choisir un port aléatoire pour nous car plus tard, nous accédons à ce service avec son nom.

Enfin, nous devons indiquer à notre client où il doit localiser le registre:

spring:
  application:
    name: spring-cloud-eureka-client
server:
  port: 0
eureka:
  client:
    serviceUrl:
      defaultZone: ${EUREKA_URI:http://localhost:8761/eureka}
  instance:
    preferIpAddress: true

Lorsque nous avons décidé de configurer notre client Eureka de cette manière, nous avons pensé que ce type de service devrait ensuite être facilement évolutif.

Nous allons maintenant exécuter le client et pointer à nouveau notre navigateur vershttp://localhost:8761, pour voir son statut d'enregistrement sur le tableau de bord Eureka. En utilisant le tableau de bord, nous pouvons effectuer d'autres configurations, par exemple. lier la page d'accueil d'un client enregistré au tableau de bord à des fins administratives. Les options de configuration sortent toutefois du cadre de cet article.

image

4. Feindre le client

Pour finaliser notre projet avec trois microservices dépendants, nous allons maintenant implémenter une application Web consommantREST en utilisantSpring Netflix Feign Client.

Considérez lesFeign comme desSpring RestTemplateensibles à la découverte utilisant des interfaces pour communiquer avec les points de terminaison. Cette interface sera automatiquement implémentée lors de l'exécution et au lieu deservice-urls, elle utiliseservice-names.

SansFeign, nous aurions à transférer automatiquement une instance deEurekaClient dans notre contrôleur avec laquelle nous pourrions recevoir une information de service parservice-name en tant qu'objetApplication.

Nous utiliserions ceApplication pour obtenir une liste de toutes les instances de ce service, en choisir une appropriée et utiliser ceInstanceInfo pour obtenir le nom d'hôte et le port. Avec cela, nous pourrions faire une requête standard avec n'importe quelhttp client.

Par exemple:

@Autowired
private EurekaClient eurekaClient;

public void doRequest() {
    Application application =
      eurekaClient.getApplication("spring-cloud-eureka-client");
    InstanceInfo instanceInfo = application.getInstances().get(0);
    String hostname = instanceInfo.getHostName();
    int port = instanceInfo.getPort();
    // ...
}

UnRestTemplate peut également être utilisé pour accéder aux services client deEureka par son nom, mais cette rubrique va au-delà de cette description.

Pour configurer notre projetFeign Client, nous allons ajouter les quatre dépendances suivantes à sespom.xml:


    org.springframework.cloud
    spring-cloud-starter-feign


    org.springframework.cloud
    spring-cloud-starter-netflix-eureka-client


    org.springframework.boot
    spring-boot-starter-web


    org.springframework.boot
    spring-boot-starter-thymeleaf

LeFeign Client se trouve dans le packagespring-cloud-starter-feign. Pour l'activer, nous devons annoter un@Configuration avec@EnableFeignClients. Pour l'utiliser, nous annotons simplement une interface avec@FeignClient(“service-name”) et la connectons automatiquement à un contrôleur.

Une bonne méthode pour créer de telsFeignClients est de créer des interfaces avec les méthodes annotées@RequestMapping et de les placer dans un module séparé. De cette façon, ils peuvent être partagés entre le serveur et le client. Côté serveur, vous pouvez les implémenter en tant que@Controller, et côté client, ils peuvent être étendus et annotés en tant que@FeignClient.

De plus, lesspring-cloud-starter-eureka package doivent être inclus dans le projet et activés en annotant la classe d'application principale avec@EnableEurekaClient.

Les dépendancesspring-boot-starter-web etspring-boot-starter-thymeleaf sont utilisées pourpresent a view, contenant les données extraites de notre serviceREST.

Ce sera notre interfaceFeign Client:

@FeignClient("spring-cloud-eureka-client")
public interface GreetingClient {
    @RequestMapping("/greeting")
    String greeting();
}

Ici, nous allons implémenter la classe d'application principale qui agit simultanément en tant que contrôleur:

@SpringBootApplication
@EnableFeignClients
@Controller
public class FeignClientApplication {
    @Autowired
    private GreetingClient greetingClient;

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

    @RequestMapping("/get-greeting")
    public String greeting(Model model) {
        model.addAttribute("greeting", greetingClient.greeting());
        return "greeting-view";
    }
}

Ce sera le modèle HTML pour notre vue:



    
        Greeting Page
    
    
        

Au moins le fichier de configuration deapplication.yml est presque le même que dans l'étape précédente:

spring:
  application:
    name: spring-cloud-eureka-feign-client
server:
  port: 8080
eureka:
  client:
    serviceUrl:
      defaultZone: ${EUREKA_URI:http://localhost:8761/eureka}

Nous pouvons maintenant construire et exécuter ce service. Enfin, nous allons pointer notre navigateur surhttp://localhost:8080/get-greeting et il devrait afficher quelque chose comme ce qui suit:

Hello from SPRING-CLOUD-EUREKA-CLIENT!

5. «TransportException: Impossible d’exécuter la demande sur un serveur connu»

Lors de l'exécution du serveur Eureka, nous rencontrons souvent des exceptions telles que:

com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server

Fondamentalement, cela se produit en raison d'une mauvaise configuration dansapplication.properties ouapplication.yml. Eureka fournit deux propriétés pour le client qui peuvent être configurables.

  • registerWithEureka: Si nous définissons cette propriété commetrue, alors que le serveur démarre, le client intégré essaiera de s'enregistrer auprès du serveur Eureka.

  • fetchRegistry: Le client intégré essaiera de récupérer le registreEureka si nous configurons cette propriété sur true.

Maintenantwhen we start up the Eureka server, we don’t want to register the inbuilt client to configure itself with the server.

Si nous marquons les propriétés ci-dessus commetrue (ou ne les configurons pas car elles sonttrue par défaut) lors du démarrage du serveur, le client intégré essaie de s'enregistrer avec lesEureka serveur et essaie également de récupérer le registre qui n'est pas encore disponible. En conséquence, nous obtenonsTransportException.

Nous ne devons donc jamais configurer ces propriétés en tant quetrue dans les applications serveur deEureka. Les paramètres corrects à mettre enapplication.yml sont indiqués ci-dessous:

eureka:
  client:
    registerWithEureka: false
    fetchRegistry: false

6. Conclusion

Comme nous l'avons vu, nous sommes désormais en mesure de mettre en œuvre un registre de service à l'aide deSpring Netflix Eureka Server et d'enregistrer certainsEureka Clients avec.

Étant donné que notreEureka Client de l'étape 3 écoute sur un port choisi au hasard, il ne connaît pas son emplacement sans les informations du registre. Avec unFeign Client et notre registre, nous pouvons localiser et consommer le serviceREST, même lorsque l'emplacement change.

Enfin, nous avons une vue d'ensemble de l'utilisation de la découverte de services dans une architecture de microservices.

Comme d'habitude, vous trouverez les sourceson GitHub, qui incluent également un ensemble de fichiers liés àDocker à utiliser avecdocker-compose pour créer des conteneurs à partir de notre projet.