Понимание Spring Cloud Discovery Eureka Client с примером
1. Цель статьи
В распределенной системе (Distributed System), услуги (приложения) должны зарегистрироваться с "Service Registration" (Регистрация услуг) чтобы они смогли найти друг друга.В предыдущей статье мы создали "Service Registration" используя технологию Netflix (Spring Cloud Netflix Eureka Server). Вы можете просмотреть даннуюю статью по ссылке ниже:
OK, в данной статье мы обсудим, как конфигурировать для услуги (приложения) в распреденной системе, чтобы она стала Eureka Client. То есть она будет зарегистрирована с "Serivce Registration" (Eureka Server).
Еureka Client получит список других Eureka Client в системе, мы будет манипулировать с данным списком с кодом Java.
2. Создать проект Spring Boot
На Eclipse создать проект Spring Boot.
- Name: SpringCloudDiscoveryEurekaClient
- Group: org.o7planning
- Artifact: SpringCloudDiscoveryEurekaClient
- Description: Spring Cloud Discovery (Eureka Client)
- Package: org.o7planning.eurekaclient
Проект создан:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.o7planning</groupId>
<artifactId>SpringCloudDiscoveryEurekaClient</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>SpringCloudDiscoveryEurekaClient</name>
<description>Spring Cloud Discovery (Eureka Client)</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Edgware.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3. @EnableEurekaClient
Использовать @EnableEurekaClient для аннотации (annotate) на приложении, вы превратите это приложение в Eureka Client.
SpringCloudDiscoveryEurekaClientApplication.java
package org.o7planning.eurekaclient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@EnableEurekaClient
@SpringBootApplication
public class SpringCloudDiscoveryEurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudDiscoveryEurekaClientApplication.class, args);
}
}
application.yml
spring:
application:
name: ABC-SERVICE # ==> This is Service-Id
---
# Items that apply to ALL profiles:
eureka:
instance:
appname: ABC-SERVICE # ==> This is a instance of ABC-SERVICE
client:
fetchRegistry: true
serviceUrl:
# defaultZone: http://my-eureka-server.com:9000/eureka
defaultZone: http://my-eureka-server-us.com:9001/eureka
# defaultZone: http://my-eureka-server-fr.com:9002/eureka
# defaultZone: http://my-eureka-server-vn.com:9003/eureka
server:
port: 8000
---
spring:
profiles: abc-service-replica01
eureka:
instance:
appname: ABC-SERVICE # ==> This is a instance of ABC-SERVICE
client:
fetchRegistry: true
serviceUrl:
defaultZone: http://my-eureka-server-us.com:9001/eureka
server:
port: 8001
---
spring:
profiles: abc-service-replica02
eureka:
instance:
appname: ABC-SERVICE # ==> This is a instance of ABC-SERVICE
client:
fetchRegistry: true
serviceUrl:
defaultZone: http://my-eureka-server-us.com:9001/eureka
server:
port: 8002
---
spring:
profiles: abc-service-replica03
eureka:
instance:
appname: ABC-SERVICE # ==> This is a instance of ABC-SERVICE
client:
fetchRegistry: true
serviceUrl:
defaultZone: http://my-eureka-server-us.com:9001/eureka
server:
port: 8003
---
spring:
profiles: abc-service-replica04
eureka:
instance:
appname: ABC-SERVICE # ==> This is a instance of ABC-SERVICE
client:
fetchRegistry: true
serviceUrl:
defaultZone: http://my-eureka-server-us.com:9001/eureka
server:
port: 8004
---
spring:
profiles: abc-service-replica05
eureka:
instance:
appname: ABC-SERVICE # ==> This is a instance of ABC-SERVICE
client:
fetchRegistry: true
serviceUrl:
defaultZone: http://my-eureka-server-us.com:9001/eureka
server:
port: 8005
4. Controller
Когда Eureka Client регистрирует с Eureka Server (Service Registration), он может получить список других Eureka Client зарегистрировавших с Eureka Server.
@Autowired
private DiscoveryClient discoveryClient;
...
// Get All Service Ids
List<String> serviceIds = this.discoveryClient.getServices();
// (Need!!) eureka.client.fetchRegistry=true
List<ServiceInstance> instances = this.discoveryClient.getInstances(serviceId);
for (ServiceInstance serviceInstance : instances) {
System.out.println("URI: " + serviceInstance.getUri();
System.out.println("Host: " + serviceInstance.getHost();
System.out.println("Port: " + serviceInstance.getPort();
}
MainController.java
package org.o7planning.eurekaclient.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MainController {
@Autowired
private DiscoveryClient discoveryClient;
@ResponseBody
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home() {
return "<a href='showAllServiceIds'>Show All Service Ids</a>";
}
@ResponseBody
@RequestMapping(value = "/showAllServiceIds", method = RequestMethod.GET)
public String showAllServiceIds() {
List<String> serviceIds = this.discoveryClient.getServices();
if (serviceIds == null || serviceIds.isEmpty()) {
return "No services found!";
}
String html = "<h3>Service Ids:</h3>";
for (String serviceId : serviceIds) {
html += "<br><a href='showService?serviceId=" + serviceId + "'>" + serviceId + "</a>";
}
return html;
}
@ResponseBody
@RequestMapping(value = "/showService", method = RequestMethod.GET)
public String showFirstService(@RequestParam(defaultValue = "") String serviceId) {
// (Need!!) eureka.client.fetchRegistry=true
List<ServiceInstance> instances = this.discoveryClient.getInstances(serviceId);
if (instances == null || instances.isEmpty()) {
return "No instances for service: " + serviceId;
}
String html = "<h2>Instances for Service Id: " + serviceId + "</h2>";
for (ServiceInstance serviceInstance : instances) {
html += "<h3>Instance: " + serviceInstance.getUri() + "</h3>";
html += "Host: " + serviceInstance.getHost() + "<br>";
html += "Port: " + serviceInstance.getPort() + "<br>";
}
return html;
}
// A REST method, To call from another service.
// See in Lesson "Load Balancing with Ribbon".
@ResponseBody
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String hello() {
return "<html>Hello from ABC-SERVICE</html>";
}
}
5. Запуск приложения на Eclipse
Для начала нужно гарантировать что вы уже запустили Eureka Server:
See the previous lesson to run an Eureka Server:
Потом вы можете запустить Eureka Client напряму на Eclipse, он будет зарегистрирован с Eureka Server.
Пройти по URL ниже, и вы можете увидеть Eureka Client зарегистрированные с Eureka Server.
6. Запуск реплик (replica)
Использовать функцию "Maven Install" чтобы создать файл jar из project. Нажать на правую кнопку мыши на проект, выбрать:
- Run As/Maven Install
И у вас есть файл jar в папке target у project.
Копировать только что созданный файл jar в определенную папкуи создать 2 файла BAT:
- abc-service-replica01.bat
- abc-service-replica02.bat
- abc-service-replica03.bat
- abc-service-replica04.bat
- abc-service-replica05.bat
abc-service-replica01.bat
java -jar -Dspring.profiles.active=abc-service-replica01 SpringCloudDiscoveryEurekaClient-0.0.1-SNAPSHOT.jar
abc-service-replica02.bat
java -jar -Dspring.profiles.active=abc-service-replica02 SpringCloudDiscoveryEurekaClient-0.0.1-SNAPSHOT.jar
abc-service-replica03.bat
java -jar -Dspring.profiles.active=abc-service-replica03 SpringCloudDiscoveryEurekaClient-0.0.1-SNAPSHOT.jar
abc-service-replica04.bat
java -jar -Dspring.profiles.active=abc-service-replica04 SpringCloudDiscoveryEurekaClient-0.0.1-SNAPSHOT.jar
abc-service-replica05.bat
java -jar -Dspring.profiles.active=abc-service-replica05 SpringCloudDiscoveryEurekaClient-0.0.1-SNAPSHOT.jar
Запустить 2 файла BAT:
На Eureka Monitor вы можете увидеть Eureka Client зарегистрированные с Eureka Server.
7. Test Discovery
OK, после запуска Eureka Client, вы можете просмотреть как он находит други Eureka Client.
Пройти по URL ниже (Заметьте, подождать 30 секунд, чтобы гарантировать Eureka Server и Eureka Client полностью обновили статусы друг друга).
- http://localhost:8000 (If Eureka Client run from Eclipse)
- http://localhost:8001 (If Eureka Client run from BAT file)
Руководства Spring Cloud
- Что такое Облачные вычисления (Cloud Computing)?
- Введение в Netflix и его технологию облачных вычислений
- Введение в Spring Cloud
- Понимание Spring Cloud Config Server с примером
- Понимание Spring Cloud Config Client с примером
- Понимание Spring Cloud Eureka Server с примером
- Понимание Spring Cloud Discovery Eureka Client с примером
- Понимание балансировки нагрузки в Spring Cloud с лентой и примером
Show More