Continue learning about SpringCloud today.

Last time we looked at the service gateway Zuul and the load balancing Ribbon

This one goes into more detail about Feign and Hystrix

The following code uses the simplest code examples, not real business code

The learning materials used in the study are as follows:

Article: SpringCloud minimalism Primer

Video: Spring Cloud from the beginning to the real world


Feign

In practice, there is a more convenient way to implement the same functionality, and this is Feign, which is now used to implement load balancing for service consumption.

What is Feign

Feign, like the Ribbon, is provided by Netflix. Feign is a declarative Web Service client that provides templates to simplify writing Web Service clients. Developers can invoke HTTP apis with simple interfaces and annotations. Spring Cloud also provides Feign integration components: Spring Cloud Feign, which integrates the Ribbon and Hystrix with plugable, annotation-based, load balancing, service circuit breaker and many other convenient functions.

Feign is a declarative Web service client, so you just need to create an interface and add annotations to the interface to bind the service provider’s interface, compared to the Ribbon + RestTemplate approach. Feign greatly simplifies code development. Feign supports a variety of annotation solutions, including Feign annotations, JAX-RS annotations, Spring MVC annotations, and more. Spring Cloud optimizes Feign by integrating the Ribbon with Eureka to make it easier to use.

The difference between Ribbon and Feign

Feign is a more convenient Web service client than the Ribbon. What are the differences between the two? Where does Feign work?

The Ribbon is a universal HTTP client tool, while Feign is based on the Ribbon. It is more flexible and easier to use. In the last lesson, we used the Ribbon + RestTemplate to implement load balancing for service invocation. Feign allows you to directly invoke a service through a declarative interface, which is much more convenient than the Ribbon. You only need to create interfaces and add annotations. Can realize the load balance of service consumption.

The characteristics of Feign

  • Feign is a declarative Web Service client.
  • Support Feign annotations, JAX-RS annotations, Spring MVC annotations.
  • Feign is based on the Ribbon and is much easier to use.
  • Feign integrates Hystrix with service fuse.

Feign code implementation

  • Create Module, pom.xml
<dependencies>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    <version>2.0.2. RELEASE</version>
  </dependency>
 
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>2.0.2. RELEASE</version>
  </dependency>
</dependencies>
Copy the code
  • Create the configuration file application.yml
server:
  port: 8050
spring:
  application:
    name: feign
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
Copy the code
  • Creating a startup class
package com.janeroad;

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

@SpringBootApplication
@EnableFeignClients
public class FeignApplication {
    public static void main(String[] args) { SpringApplication.run(FeignApplication.class,args); }}Copy the code
  • Create declarative interfaces
package com.janeroad.feign;

import com.janeroad.entity.Student;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.Collection;

@FeignClient(value = "provider")
public interface FeignProviderClient {
    @GetMapping("/student/findAll")
    public Collection findAll(a);

    @GetMapping("/student/index")
    public String index(a);
}
Copy the code
  • Handler
package com.janeroad.controller;

import com.janeroad.entity.Student;
import com.janeroad.feign.FeignProviderClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collection;

@RestController
@RequestMapping("/feign")
public class FeignHandler {

    @Autowired
    private FeignProviderClient feignProviderClient;

    @GetMapping("/findAll")
    public Collection findAll(a){
        return feignProviderClient.findAll();
    }

    @GetMapping("/index")
    public String index(a){
        returnfeignProviderClient.index(); }}Copy the code
  • Service circuit breaker, application. Yml adds circuit breaker mechanism.
server:
  port: 8050
spring:
  application:
    name: feign
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
feign:
  hystrix:
    enabled: true
Copy the code

Feign.hystrix. enabled: Indicates whether to enable the fuse.

  • Create FeignProviderClient interface implementation class FeignError, define fault tolerant processing logic, through@ComponentThe annotations inject the FeignError instance into the IoC container.
package com.janeroad.feign.impl;

import com.janeroad.entity.Student;
import com.janeroad.feign.FeignProviderClient;
import org.springframework.stereotype.Component;

import java.util.Collection;

@Component
public class FeignError implements FeignProviderClient {
    @Override
    public Collection findAll(a) {
        return null;
    }

    @Override
    public String index(a) {
        return "Server maintenance......"; }}Copy the code
  • Pass through the FeignProviderClient definition@FeignClientThe Fallback property sets the mapping.
package com.janeroad.feign;

import com.janeroad.entity.Student;
import com.janeroad.feign.impl.FeignError;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.Collection;

@FeignClient(value = "provider",fallback = FeignError.class)
public interface FeignProviderClient {
    @GetMapping("/student/findAll")
    public Collection findAll(a);

    @GetMapping("/student/index")
    public String index(a);
}
Copy the code

Start the registry with the Provider port 8010, Provider port 8011, and Feign respectively

In the browser, visit http://localhost:8761. The following page is displayed

You can see that two providers and Feign have been registered in the registry, and then test the Feign interface using the Postman tool, as shown in the figure below.

  • The.findall interface

  • Load balancing

Feign also provides fault tolerance. If the service Provider is faulty and cannot be accessed, an error is displayed when you directly access Feign, as shown in the following figure.

It is very simple that the interaction mode of directly returning the error status code is not friendly. Instead of the error status code, the corresponding prompt information can be given to the user through the fault tolerance mechanism, so that the interaction mode is more friendly. The fault tolerance mechanism is very simple. To add the configuration.

server:
  port: 8050
spring:
  application:
    name: feign
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
feign:
  hystrix:
    enabled: true
Copy the code

Feign.hystrix. enabled: Indicates whether to enable the fuse.

Create FeignError, the implementation class of the FeignProviderClient interface, define the fault tolerant handling logic, and inject the FeignError instance into the IoC container via @Component.

@Component
public class FeignError implements FeignProviderClient {
    @Override
    public String index(a) {
        return "Server maintenance....";
    }

    @Override
    public Collection findAll(a) {
        return null;
    }

    @Override
    public Student findById(long id) {
        return null;
    }

    @Override
    public void save(Student student) {}@Override
    public void update(Student student) {}@Override
    public void deleteById(long id) {}}Copy the code

Set the mapping at the FeignProviderClient definition via the fallback property of @FeignClient.

@FeignClient(value = "provider",fallback = FeignError.class)
public interface FeignProviderClient {}Copy the code

Start the registry and Feign. At this point, no service Provider is registered and access the Feign interface directly, as shown in the figure below.

Hystrix

As mentioned above, Feign provides fault tolerance, which is implemented in conjunction with Hystrix.

What is microservice fault tolerance

In a distributed system, the various micro service call each other, depend on each other, the actual running environment may because a micro causes all kinds of a kind of service is not available, is dependent on the service of other services will appear response time is too long or request failed, if the number of times the problem is more, To a certain extent, the whole system can crash. On the premise of not changing the invocation relationship of each micro-service, the processing scheme can be set in advance for these errors. When problems occur, the whole system can adjust autonomously, which is the principle of the fault tolerance mechanism of micro-service to find faults and deal with them in time.

What is the Hystrix

Hystrix, an open source project from Netflix, is an implementation of the fuse model, which is like a fuse in a circuit. When a unit fails, it burns the fuse to prevent the spread of the fault, which is also the fault tolerance mechanism of microservices architecture. The main purpose of Hystrix is to return fallback processing to the service consumer when the service provider fails and becomes inaccessible, resulting in either a slow response time or a direct exception thrown.

Hystrix design principles:

  • A service isolation mechanism to prevent the failure of a service provider from affecting the entire system.
  • Service degradation mechanism, which returns a fallback processing mechanism to the service consumer when a service fails.
  • Circuit breakers, which are quickly activated and repaired when the failure rate of service consumer requests reaches a certain value.
  • Provides real-time monitoring and alarm functions to quickly discover service faults.
  • Provides the real-time configuration modification function to ensure that faults can be rectified in a timely manner.

Having demonstrated Hystrix’s circuit-breaker mechanism, I now focus on another important Hystrix feature — data monitoring.

In addition to providing fault tolerance for services, Hystrix also provides monitoring of requests. This function needs to be used in conjunction with Spring Boot Actuators, which provide health monitoring and data statistics for services. The hystrix-Stream node can be used to obtain the monitored request data. The Dashboard component provides visual monitoring of the data. Hystrix data monitoring is then implemented through code.

Hystrix code implementation

  • Create Maven, pom.xml
<dependencies>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    <version>2.0.2. RELEASE</version>
  </dependency>
 
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>2.0.2. RELEASE</version>
  </dependency>
 
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
    <version>2.0.7. RELEASE</version>
  </dependency>
 
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    <version>2.0.2. RELEASE</version>
  </dependency>
 
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    <version>2.0.2. RELEASE</version>
  </dependency>
</dependencies>
Copy the code
  • Create the configuration file application.yml
server:
  port: 8060
spring:
  application:
    name: hystrix
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
feign:
  hystrix:
    enabled: true
management:
  endpoints:
    web:
      exposure:
        include: 'hystrix.stream'
Copy the code
  • Creating a startup class
package com.janeroad;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients
@EnableCircuitBreaker
@EnableHystrixDashboard
public class HystrixApplication {
    public static void main(String[] args) { SpringApplication.run(HystrixApplication.class,args); }}Copy the code

Notes:

EnableCircuitBreaker: Declare data monitoring enabled

EnableHystrixDashboard: Declare enabling visual data monitoring

  • Handler
package com.janeroad.controller;

import com.janeroad.entity.Student;
import com.janeroad.feign.FeignProviderClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collection;

@RestController
@RequestMapping("/hystrix")
public class HystrixHandler {
    @Autowired
    private FeignProviderClient feignProviderClient;

    @GetMapping("/findAll")
    public Collection findAll(a){
        return feignProviderClient.findAll();
    }

    @GetMapping("/index")
    public String index(a){
        returnfeignProviderClient.index(); }}Copy the code
  • After successful startup, accesshttp://localhost:8060/actuator/hystrix.streamCan monitor request data,
  • accesshttp://localhost:8060/hystrix, you can see the visual monitoring interface. Enter the address node to be monitored to see the visual data monitoring of the node.

In order to start the registry, the Provider, Hystrix, can directly access the URL in the red box to monitoring data, input http://localhost:8060/actuator/hystrix.stream in your browser’s address bar

No client request at this time, so there is no data, visit http://localhost:8060/hystrix/index

Once again, visit http://localhost:8060/actuator/hystrix.stream

Monitoring data is displayed, but it is not intuitive. You can monitor data more intuitively by using a visual interface. You can add dashboards and add related dependencies in POM.xml.

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

Add the @enableHystrixDashboard annotation to the HystrixApplication class definition.

@SpringBootApplication
@EnableFeignClients
@EnableCircuitBreaker
@EnableHystrixDashboard
public class HystrixApplication {
    public static void main(String[] args) { SpringApplication.run(HystrixApplication.class,args); }}Copy the code

Go to http://localhost:8060/hystrix

In the red box enter http://localhost:8060/actuator/hystrix.stream and Tiltle, click Monitor Stream button, as shown in the figure below

Here comes the visual monitoring data interface.