SpringCloud Eureka easy to use learning

The following is an excerpt from SpinrgCloud microservice architecture development practice

Service governance

There are two options for spring cloud service governance, Consul and Neiflix's Eureka.
Eureka is an open-source service governance product of Netflix. Spirng Cloud has secondary encapsulated it to form the Spirng Cloud Netflix sub project. Erueka provides a service registry, a service discovery client, and a UI application for registering services. From Eureka's point of view, nodes are equal to each other. Stopping some registration will not affect the whole application. Only one node can survive in time and can also manage services normally. Even if all service registration nodes are down, the service instance list information cached in Eureka client can enable service consumers to work normally, so as to ensure the robustness of mutual calls between microservices and the elasticity of applications.

Client load balancing

Spring cloud realizes client load balancing by encapsulating the Netflix open source project ribbon. Ribbon integrates seamlessly with Eureka by default. When the client starts, it obtains a service registration list from Eureka server and maintains it locally. When the service consumer needs to call the service, ribbon will select an appropriate service provider for access according to the load balancing strategy. By integrating the Feign project of Netflix, spring cloud provides developers with declarative service calls, which simplifies the call processing between microservices. In addition, the default Feign project inherits the ribbon, so that the declarative call also supports the balancing function of the client.

Microservice, fault tolerance, degradation

In SpirngCloud, by integrating the Netflix subproject hystrix and the @ HystrixCommand annotation provided, we can provide fault tolerance, fallback, degradation and other functions for the microservices we develop. By default, hystrix is also integrated into the Feign subproject. Hystrix is created according to the "circuit breaker" mode. When hystrix monitors that a service unit fails, it will enter the service fuse Chul and Bing will return a qualified service fallback to the caller instead of waiting for a long time or throwing a call exception, so as to ensure that the orange of the service caller will not be occupied unnecessarily for a long time, Avoid the avalanche effect caused by the spread of applause in English red. The hystrix Dashboard can monitor the time, request, success rate, etc. consumed by each service call.

Version used in this test

SpringBoot: 2.6.2 

SpringCloud: 2021.0.0

 

Eureka service registry

maven configuration

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.demo</groupId>
    <artifactId>service-discovery</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>service-discovery</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</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>2021.0.0</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>

In addition to the basic version number configuration of SpringBoot and SpringCloud, the maven dependency of Eureka server must be added. The web module dependency can be omitted. If not, the default dependent web module of Eureka server will be used

Startup class

package com.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class ServiceDiscoveryApplication {

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

}

The @ EnableEurekaServer annotation must be added

Parameter configuration

server.port=9999
eureka.instance.appname=eureka
eureka.instance.hostname=127.0.0.1
eureka.instance.prefer-ip-address=true
## Currently, it is the eureka registration service center and is a stand-alone version. It is not necessary to register the current service with eureka. Set it to false
eureka.client.register-with-eureka=false
## You do not need to pull the service list from the eureka registration service center and set it to false
eureka.client.fetch-registry=false
## eureka registration service center address
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
eureka.server.wait-time-in-ms-when-sync-empty=0
eureka.server.enable-self-preservation=false

At this point, the Eureka service registration center is set up. After startup, access the address http://127.0.0.1:9999/ , you can access the Eureka registration management interface, where you can see the registered services and other information

Service provider

maven configuration

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.2</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.demo</groupId>
    <artifactId>service-product</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>service-product</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</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-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>2021.0.0</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>

In addition to the basic version number configuration of SpringBoot and SpringCloud, the maven dependency of Eureka client must be added. Since the provided is a web service, the web related starter dependency also needs to be added

controller

package com.demo.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.demo.entity.ResultEntity;

@RestController
@RequestMapping
public class ServerController {
    private Logger logger = LoggerFactory.getLogger(ServerController.class);
    
    @RequestMapping("/getData/{id}")
    public Object getData(@PathVariable String id) {
        logger.info("server receive id: {}", id);
        return new ResultEntity(true, "result: "+id);
    }
}

Return entity class

package com.demo.entity;

public class ResultEntity {

    private boolean success;
    private String msg;

    public ResultEntity(boolean success, String msg) {
        this.success = success;
        this.msg = msg;
    }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

}

Startup class

package com.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * The @ EnableDiscoveryClient can be omitted for later versions
 * @author admin
 *
 */
@SpringBootApplication
//@EnableDiscoveryClient
public class ServiceProductApplication {

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

}

Parameter configuration

## Automatic port allocation. If automatic allocation will have an impact, you can specify a port. For example, if the specified port can be accessed through the firewall, you need to specify a port
server.port=0
spring.application.name=service-provider
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://127.0.0.1:9999/eureka/

Service consumers

maven configuration

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.2</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.demo</groupId>
    <artifactId>service-consumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>service-consumer</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <spring-cloud.version>2021.0.0</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</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-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>

In addition to the basic version number configuration of SpringBoot and SpringCloud, the maven dependency of Eureka client must be added. Web projects also need to add web related dependencies. Since fegin is used, feign related dependencies also need to be added.

controller

package com.demo.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.demo.entity.ResultEntity;
import com.demo.service.ConsumerService;

@RestController
@RequestMapping
public class ConsumerController {

    private Logger logger = LoggerFactory.getLogger(ConsumerController.class);
    
    @Autowired
    private ConsumerService ConsumerService;
    
    @RequestMapping("/getData/{id}")
    public Object getData(@PathVariable String id) {
        logger.info("concumer id: {}", id);
        ResultEntity data = ConsumerService.getData(id);
        return data;
    }
}

Receiving entity class (corresponding to the returned entity class of the service provider)

package com.demo.entity;

public class ResultEntity {

    private boolean success;
    private String msg;

    public ResultEntity(boolean success, String msg) {
        this.success = success;
        this.msg = msg;
    }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

}

Startup class

package com.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
//@EnableDiscoveryClient
@EnableFeignClients
public class ServiceConsumerApplication {

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

}

Parameter configuration

## Automatic port assignment
server.port=8081
spring.application.name=service-consumer
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=true
eureka.client.service-url.defaultZone=http://127.0.0.1:9999/eureka/

 

For testing, start the eureka registry first, start the service provider, and finally start the service consumer. Access the interface: http://127.0.0.1:8081/getData/11 , the returned results are as follows

 

Where 11 is id, other values can also be used, and will be returned as is in the result.

At this point, a complete service governance process demo of service registration and consumption in eureka service registration ends.

 

matters needing attention:

1. In the lower version of spring cloud, both server providers and service consumers need to add the @ enablediscovery client annotation, but not in the higher version. Spring cloud will automatically open the eureka client according to the introduced starter

2. If the service provider returns a string and only uses Object to receive the results obtained remotely, the following exceptions may occur:

org.springframework.web.client.UnknownContentTypeException: Could not extract response:
no suitable HttpMessageConverter found for response type [class java.lang.Object] and content type [text/plain;charset=UTF-8]

You can use the entity object or map instead, or directly use the string to receive. If you use the entity object to return and receive data, you need to add get and set methods to the entity class, otherwise the following exceptions may occur

Resolved [org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation]

3. Both @ EnableEurekaClient and @ EnableDiscoveryClient can let the registry discover and scan the service. The former is only valid for Eureka, and the latter can be valid for Eureka, Zookeeper, Consul and other registries;

4. If feign is used for remote call, you must add @ EnableFeignClients on the service consumer side, otherwise the feign call will not work. In addition, if you remove the implementation class callback that implements the customized fegin related interface, the fegin interface call cannot be injected into the controller, and the following errors may occur when the service is started

Field ConsumerService in com.demo.controller.ConsumerController required a bean of type 'com.demo.service.ConsumerService' that could not be found.

Keywords: Spring Cloud

Added by ClevaTreva on Thu, 20 Jan 2022 23:27:16 +0200