Spring-Cloud EurAKA is a component in the Spring Cloud collection that is an integration with EurAKA for service registration and discovery. Eureka is an open source framework within Netflix. It’s for service registry management like ZooKeeper and Consul, which Spring-Cloud also integrates with.

Set up the Eureka service registry

Introduce the following dependencies

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <! - the latest version of eureka server package - > < the dependency > < groupId > org. Springframework. Cloud < / groupId > <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies> <! -- SpringCloud dependencies, Play the role of management version - > < dependencyManagement > < dependencies > < the dependency > < groupId > org. Springframework. Cloud < / groupId > <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR9</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>

Version correspondence between Spring Cloud and Spring Boot

Release Train Boot Version
X 2020.0. aka Ilford X 2.4.
Hoxton 2.2. X, 2.3. X (Starting with SR5)
Greenwich X 2.1.
Finchley X 2.0.
Edgware X 1.5.
Dalston X 1.5.

Add on the boot class@EnableEurekaServerThe comment indicates that this is an Eureka server

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

Add some configuration in Application.properties

Server. port=8080 spring.application.name= eureka-server # IP eureka.instance.hostname=localhost eureka.instance.statusPageUrl=http://${eureka.instance.hostname}:${server.port}/info eureka.instance.healthCheckUrl=http://${eureka.instance.hostname}:${server.port}/health Eureka. Instance. HomePageUrl = {http://$eureka. The instance. The hostname} / # indicates whether or not the service registry to eureka server, because itself is had the service side, # eureka=false # eureka=false # eureka=false # eureka=false # eureka=false # eureka=false # eureka=false # eureka=false # eureka=false # eureka. Client. Fetch-Registry =false # Specify the address of the eureka server. The default value is http://localhost:8761/eureka had been specified server address for another 8081 Eureka server address Eureka. Client. ServiceUrl. DefaultZone = {http://$eureka. The instance. The hostname} : ${server port} / had been / # is used to define service contract task calls time interval, 30 seconds by default eureka. Client. ServiceUrl. Registry - fetch - interval - seconds = 5

After the configuration is complete, start the service and visit http://localhost:8080/

The Instances currently registered with Eureka list is empty because no Eureka client has registered the service

Set up the Provider service provider

Introduce the following dependencies

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <! > <dependency> < grouppid >org.springframework.boot</ grouppid > <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies> <! -- SpringCloud dependencies, Play the role of management version - > < dependencyManagement > < dependencies > < the dependency > < groupId > org. Springframework. Cloud < / groupId > <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR9</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>

Add to the boot class@EnableDiscoveryClientThe comment indicates that this is an Eureka client

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

Then write a TestController to provide some REST services to the outside world

@RestController public class TestController { @GetMapping("/hello") public String hello() { return "hello world"; }}

Add some configuration in Application.properties

Port: 8081 Server. port=8082 Server. port=8082 Spring.Application.Name =Server-Provider # This service name is used by future service consumers when they want to get the interface in the TestController above. Make the function of Eureka client more intuitive (i.e. register the service with the server and periodically fetch the service cache from the server to the local) eureka.client.register-with-eureka=true eureka.client.fetch-registry=true # Specify the address of the Eureka server, Here for the above definition of Eureka. Eureka server address client. ServiceUrl. DefaultZone = http://localhost:8080/eureka/, http://localhost:8081/eureka/ # The access path can display the IP address eureka.instance.prefer-ip-address=true

Once configured, start eureka-client and you will see a successful registration message from the console

Registered Applications size is zero : true
Application version is -1: true
Getting all instance registry info from the eureka server
The response status is 200
Starting heartbeat executor: renew interval is: 30
InstanceInfoReplicator onDemand update allowed rate per min is 4
Discovery Client initialized at timestamp 1611244216061 with initial instances count: 0
Registering application SERVER-PROVIDER with eureka with status UP
Saw local status change event StatusChangeEvent [timestamp=1611244216076, current=UP, previous=STARTING]
DiscoveryClient_SERVER-PROVIDER/DESKTOP-7LUOFJF.lan:Server-Provider:8081: registering service...
Tomcat started on port(s): 8081 (http) with context path ''
Updating port to 8081
DiscoveryClient_SERVER-PROVIDER/DESKTOP-7LUOFJF.lan:Server-Provider:8081 - registration status: 204

Visit http://localhost:8082/ again, and you can see that the Server-Providerde service has already appeared in the list of services

UP for the meaning of online (if had the client normally closed, then the state will be DOWN here), click on the back of the link http://192.168.68.233:8081/actuator/info will/info to access this service interface:

{"app":{"name":"Server-Provider"}}

At this point close the Eureka client and refresh http://localhost:8080/ again

You can see that although the Eureka client has been closed, the service is still in the list of service services on the Eureka server page, and the red text on the page prompts

EMERGENCY! Eureka MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY're NOT. Renewals ARE LESSER THAN THRESHOLD AND lead to THE death INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.

Basically, Eureka has gone into protective mode. After deployment, Eureka client may be unable to send heartbeat to Eureka server due to network problems. At this time, Eureka server determines that Eureka client is down, even though the Eureka client is still running normally. Protected mode solves this problem. If the Eureka server loses too many Eureka clients at the same time in a short period of time, the Eureka server will go into protected mode and not remove these clients. Since there is only one Eureka client service deployed here, closing the client satisfies the condition of “losing too many Eureka clients in a short time”.

In development, we can turn off the protected mode and add a configuration to the Eureka server

eureka.server.enable-self-preservation= false

Activate the service monitoring interaction

Introduce the following dependencies

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Add some configuration in Application.properties

Actuator /+ Endpoint name can be used to retrieve information from all endpoints Health, Info, Metrics. The default open health and info, the metrics is not open to the default management endpoints. Web. Exposure. Include = * # did not open the physical/health, we get the information is {" status ":" UP "}, The value of status may also be DOWN. After open print detailed information management. The endpoint. Health. The show - the details = always info. The app. Name = Server - the Provider

Access path

The localhost is accessed according to the IP and hostname of the server it is deploying. Info and health are open by default, and metrics are not

  • Heartbeat check http://localhost:8081/actuator/info
  • Health check http://localhost:8081/actuator/health
  • Indicators of http://localhost:8081/actuator/metrics

Eureka cluster

The Ureka server plays an important role, as all Eureka clients register their services with the Eureka server and make them available to all service consumers. If the single-node Eureka server goes down, then all the services can’t be accessed properly, which would be catastrophic. To improve the availability of Eureka servers, we typically cluster them, where multiple Eureka servers are deployed at the same time and can synchronize their services with each other.

The following two configurations were turned off when we built the Eureka server

eureka.client.register-with-eureka=false

eureka.client.fetch-registry=false

In fact, in the Eureka clustering pattern, enabling these two parameters allows the current Eureka server to register itself as a service with another Eureka server and obtain services from other Eureka servers for synchronization. So here we set these two parameters to true (the default is true) and let’s start building the Eureka server cluster. For simplicity we will build the Eureka server cluster on only two nodes.

The two applications.properties are configured as follows

  • Eureka server on port 8080
Server. port=8080 spring.application.name= eureka-server # IP eureka.instance.hostname=localhost eureka.instance.statusPageUrl=http://${eureka.instance.hostname}:${server.port}/info eureka.instance.healthCheckUrl=http://${eureka.instance.hostname}:${server.port}/health Eureka. Instance. HomePageUrl = {http://$eureka. The instance. The hostname} / # indicates whether or not the service registry to eureka server, because itself is had the service side, # eureka=false # eureka=false # eureka=false # eureka=false # eureka=false # eureka=false # eureka=false # eureka=false # eureka=false # eureka. Client. Fetch-Registry =false # Specify the address of the eureka server. The default value is http://localhost:8761/eureka had been specified server address for another 8081 Eureka server address Eureka. Client. ServiceUrl. DefaultZone = {http://$eureka. The instance. The hostname} : # 8081 / had been/is used to define service contract task calls time interval, 30 seconds by default eureka. Client. ServiceUrl. Registry - fetch - interval - seconds = 5 # close protection mode eureka. Server enable - self - preservation = false
  • Eureka server on port 8081
Server. port=8081 spring.application.name= eureka-server # IP eureka.instance.hostname=localhost eureka.instance.statusPageUrl=http://${eureka.instance.hostname}:${server.port}/info eureka.instance.healthCheckUrl=http://${eureka.instance.hostname}:${server.port}/health Eureka. Instance. HomePageUrl = {http://$eureka. The instance. The hostname} / # indicates whether or not the service registry to eureka server, because itself is had the service side, # eureka=false # eureka=false # eureka=false # eureka=false # eureka=false # eureka=false # eureka=false # eureka=false # eureka=false # eureka. Client. Fetch-Registry =false # Specify the address of the eureka server. The default value is http://localhost:8761/eureka had been specified server address for another 8080 Eureka server address Eureka. Client. ServiceUrl. DefaultZone = {http://$eureka. The instance. The hostname} : # 8080 / had been/is used to define service contract task calls time interval, 30 seconds by default eureka. Client. ServiceUrl. Registry - fetch - interval - seconds = 5 # close protection mode eureka. Server enable - self - preservation = false

Set up Consumer to serve consumers

Eureka client is both a service provider and a service consumer, that is, its own interface may be accessed by other services, and may also call other service interfaces

Let’s introduce dependencies

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <! -- SpringCloud dependencies, Play the role of management version - > < dependencyManagement > < dependencies > < the dependency > < groupId > org. Springframework. Cloud < / groupId > <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR9</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>

Add to the entry class@EnableDiscoveryClientAnnotations are used to discover and register services, and to configure oneRestTemplate BeanAnd then plus@LoadBalancedComments to enable load balancing

@SpringBootApplication @EnableDiscoveryClient public class SpringCloudConsumerApplication { @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(SpringCloudConsumerApplication.class, args); }}

Write a TestController to consume the service

@RestController public class TestController { @Autowired private RestTemplate restTemplate; /** * Inject a RESTTemplate, which is used in GetInfo to get the service balanced and consume it. * You can see that we use the service name (server-provider) to obtain the service, rather than the traditional IP and port form. * This shows the benefits of using Eureka to get the service, as long as we keep the name of the service unchanged, * * @return */ @getMapping ("/info") public String getInfo() {return this.restTemplate.getForEntity("http://Server-Provider/hello", String.class).getBody(); }}

Add some configuration in Application.properties

Server. port=8083 Server. port=8083 Server. port=8083 Server. port=8083 Server.consumer Spring.Application.Name =Server-Consumer # This service name is used by subsequent service consumers when they want to get the interface in the TestController above. Make the function of Eureka client more intuitive (i.e. register the service with the server and periodically fetch the service cache from the server to the local) eureka.client.register-with-eureka=true eureka.client.fetch-registry=true # Specify the address of the Eureka server, Here for the above definition of Eureka. Eureka server address client. ServiceUrl. DefaultZone = http://localhost:8080/eureka/, http://localhost:8081/eureka/ # The access path can display the IP address eureka.instance.prefer-ip-address=true

Start the project, visit http://localhost:8083/info

Eureka adds authentication

For security reasons, we may add user authentication to the Eureka server. We introduced Spring-Security dependencies in eureka-server

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Then configure the user name and password in Application.yml

spring.security.user.name=admin
spring.security.user.password=123456

Eureka server configured with a password, after all the Eureka. Client. ServiceUrl. DefaultZone configuration must also be configured on the user name and password, format for: Eureka. Client. ServiceUrl. DefaultZone = http://${userName} : ${password} @ ${hosetname} : ${port} / had been /, such as:

eureka.client.serviceUrl.defaultZone=http://admin:123456@${eureka.instance.hostname}:8080/eureka/

After repackaging and deployment, visit http://localhost:8080/, the page will pop up the authentication window, enter the user name and password to access

Eureka configuration

Common configuration options in Eureka and what they represent

configuration meaning The default value
eureka.client.enabled Whether to enable Eureka Client true
eureka.client.register-with-eureka Indicates whether to register yourself with Eureka Server true
eureka.client.fetch-registry Indicates whether to obtain registered service information from Eureka Server true
eureka.client.serviceUrl.defaultZone Configure the Eureka Server address to register the service and get the service http://localhost:8761/eureka
eureka.client.registry-fetch-interval-seconds The default value is 30 seconds, which means every 30 seconds to fetch the service from the Eureka Server and cache it 30
eureka.instance.lease-renewal-interval-in-seconds The time, in seconds, between sending a heartbeat to the Eureka Server for service renewal 30
eureka.instance.lease-expiration-duration-in-seconds Define service failure time, that is, how many seconds after Eureka Server detects that the Eureka Client does not have a heartbeat (the Client goes offline unexpectedly) 90
eureka.server.enable-self-preservation Use to enable Eureka Server self-protection true
eureka.client.instance-info-replication-interval-seconds The interval between updating instance information changes to the Eureka server, in seconds 30
eureka.client.eureka-service-url-poll-interval-seconds Polling the time between Eureka server address changes, in seconds. 300
eureka.instance.prefer-ip-address Indicates that IP is configured as not a domain name false
eureka.client.healthcheck.enabled By default, Erueka Server detects the health of Eureka Client through heartbeat. Set to true to change the mode of health detection of Eeureka Server by switching to the end point of Actuator/Health. false

There are a number of other Eureka configurations. For details, refer to the EurekAclientConfigBean, EurekaserverConfigBean, and EurekainStanceConfigBean configuration classes.

References

[1] Spring Cloud Netflix: https://cloud.spring.io/sprin…