Eureka/Feign and its introduction

Eureka

Eureka, part of Spring Cloud Netflix, is a service registry. There are three main roles in its service ecosystem: Eureka registry, service provider and service consumer. After a service provider registers with Eureka, service consumers can directly query Eureka to see what services are currently available and then select one to consume.

Eureka mainly solves the problem of service memory for consumers. Without Eureka, consumers would have to remember the address of each service and would most likely not be notified if the service provider went down or the address changed, invalidating the address. Once you join Eureka, you just need to remember the address of the Eureka registry to find all the other services.

In addition, Eureka can accept the registration of multiple services and can directly substitute for consumers for load balancing through the addition of other components, eliminating the need for consumers to manually select services.

Feign

Feign is a templated HTTP client. With Feign, you can request a remote service as if it were a local method, without having to write tedious code to create an HTTP request.

Create a parent project

The project is mainly divided into three microservices: service provider, service consumer and Eureka registry. For demonstration purposes, all three projects are running on the same host and all in a single parent project.

First create an empty project in IDEA, and then create the corresponding three Spring modules in the project:

  • EurekaServer: registry, depending onEureka Server.
  • ServiceProvider: Service provider and depends onEureka Discovery Client.Spring Web.
  • ServiceConsumer: Service consumers, dependent onOpenFeign.Eureka Discovery Client.Spring Web.

The registry

Service providers provide their addresses for invocation by registering with the registry; The service consumer requests the registry for available services.

Mainly depends on

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
Copy the code

The configuration file

# port
server.port=1000
# Specify the application name
spring.application.name=server
# whether to pull registration information from other servers
eureka.client.fetch-registry=false
Whether to register with another server
eureka.client.register-with-eureka=false
# specify the service url
eureka.client.service-url.defaultZone=http://localhost:1000/eureka

Copy the code

By default, Eureka servers assume that they are part of a cluster and periodically register themselves with other Eureka servers and get registration information from other servers. Since only one Eureka server is deployed in this project to provide registration services, these two actions are not required and are disabled by the eureka.client.fetch-registry and eureka.client.register-with-eureka properties of the configuration file.

Eureka.client. service-URL contains the name and address of each zone. DefaultZone is a special key that will be used if the client does not specify the desired zone. Typically, the address of defaultZone is the Eureka server itself.

The main class

@SpringBootApplication
@EnableEurekaServer
public class MyEurekaServerApplication {

    public static void main(String[] args) { SpringApplication.run(MyEurekaServerApplication.class, args); }}Copy the code

To start the Eureka registration service, annotate @enableEurekaserver on the native Spring Boot startup class.

Once the project is started, access localHost :1000 to see the interface provided by Eureka. If you see a warning on the screen

EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
Copy the code

It’s a normal phenomenon. The Eureka server is enabled in self-protection mode by default. Since it did not receive heartbeats from most of the servers in the cluster (there was only one Eureka server in this project, so it did not receive any heartbeats and self-protection mode did not have much impact), Eureka assumed that there was a network problem and turned on self-protection mode. In self-protection mode, registered services will not be deregistered because they do not receive heartbeats.

To disable self-protection, set the following properties in the configuration.

eureka.server.enable-self-preservation=false
Copy the code

Service provider

The service provider registers itself in the registry.

Mainly depends on

        <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>
Copy the code

The spring-cloud-starter-Netflix-Eureka-client dependency includes the implementation of the Eureka client (i.e., the service provider); Spring-boot-starter-web is used to expose the service as an HTTP endpoint.

The configuration file

# Application port
server.port=2000
# app name
spring.application.name=service
Registry address
eureka.client.service-url.defaultZone=http://localhost:1000/eureka
Copy the code

The eureka.client.service-url.defaultZone property tells the Eureka client where to find the registry.

The main class and the Controller

@SpringBootApplication
public class MyEurekaServiceApplication {

    public static void main(String[] args) { SpringApplication.run(MyEurekaServiceApplication.class, args); }}@RestController
@RequestMapping("/test")
@Slf4j
class MyController {
    @Value("${server.port}")
    private int serverPort;

    @GetMapping
    public String getHandler(a) {
        log.info("##############received call, port: " + this.serverPort);
        return "test msg"; }}Copy the code

For presentation purposes, these classes are all in the same file, same as below.

The Controller here provides a simple service: whenever you visit the /test path, return a string test MSG. If necessary, multiple service instances can be started at the same time to simulate a cluster of servers providing services.

Slf4j is an auxiliary annotation provided by Lombok to easily declare a Logger instance log in a class.

@value is an annotation provided by Spring to get information from a configuration file. In this example, the value 2000 of the previously configured property server.port=2000 is obtained and injected into the domain serverPort.

Once the service provider is started, it is automatically registered with the Eureka server specified in the configuration file. If you access the previous Eureka server interface, you can view the registered service information. Here I started three instances by changing the port number.

The /test path that accesses the service provider’s port receives the string provided by the service.

The client

Feign is a templated HTTP client. With Feign, you can request a remote service as if it were a local method, without having to write tedious code to create an HTTP request.

Feign allows clients to easily make requests and add Hystrix’s load balancing and fuse downgrading features.

Mainly depends on

        <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>
Copy the code

The spring-boot-starter-Web dependency exposes the Feign created interface as an HTTP endpoint; The Spring-Cloud-starter-OpenFeign dependency contains the implementation of Feign for creating mappings from HTTP requests to requests to the service; Spring-cloud-starter-netflix-eureka -client contains the implementation of eureka server.

The configuration file

# Application port
server.port=3000
# app name
spring.application.name=feignClient
Registry address
eureka.client.service-url.defaultZone=http://localhost:1000/eureka
Copy the code

As above, the eureka.client.service-url.defaultzone property specifies where the client should look for the registry.

Main class, Controller, and Feign mappings

@FeignClient(value = "service")
interface FeignController {
    @GetMapping("/test")
    public String getHandler(a);
}

@SpringBootApplication
@EnableFeignClients
@EnableDiscoveryClient
public class MyFeignClientApplication {

    public static void main(String[] args) { SpringApplication.run(MyFeignClientApplication.class, args); }}@RestController
@RequestMapping("/test")
class MyRestController {
    @Autowired
    FeignController feignController;

    @GetMapping
    public String getHandler(a) {
        returnfeignController.getHandler(); }}Copy the code

The FeignController interface in the class maps HTTP requests to this port to requests to the service. In this case, @feignClient (value = “service”) specifies that the call is mapped as a request to the Service service. Using @getMapping (“/test”) means that every time the method is called, the /test path is requested. In summary, every time this method is invoked, the service sends an HTTP GET request to the /test path of the service named Service. That’s where Feign comes in handy.

Annotations @enableFeignClients and @enableDiscoveryClient are required on the startup class to enable scanning of the Feign interface and discovery of the Eureka server.

The class also writes a MyRestController that maps requests to the service to method calls. The call chain is:

  • The browser sends an HTTP request to the Controller
  • The Controller invokes the method in the Feign interface when it receives the request
  • Feign maps calls to methods as requests to services in the registry and returns them

Thus, the user experiences the process of sending a request through Feign and receiving a message from a remote server.

Start the client, access the /test path of the port where the client resides, and correctly receive the string provided by the service.