The paper

Note: This sample is a change from a previous project

What is Hystrix?

  • In distributed environments, where it is inevitable that the services on which they depend will fail, Hystrix can control the interactions of these distributed systems by increasing latency and error tolerance. Hystrix creates an intermediate layer between services to prevent failures between services and provides a fallback strategy in the event of failure to increase the overall reliability and resilience of your system.
  • Chinese document

Service fusing

  • What is a service circuit breaker

The sample

Provide fallback in case of failure

  • The circuit breaker is performed on the service provider.

  • Choose one of the service providers to use Hystrix

  • Complete the following steps

  1. Import dependence
  2. Used on startup classes@EnableCircuitBreaker// Turn on the fuse
  3. The controller layerCreate an emergency method (Fallback), the use of@HystrixCommand
  • code

Rely on

    <dependencies>
        <! -- Entity class -->
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>SpringCloud-Api</artifactId>
            <version>1.0 the SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <! --test-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-netflix-eureka-client</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-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
    </dependencies>
Copy the code
  • controller
// Provides restful services
@RestController
public class DeptController {
    @Autowired
    private DeptService service;

    // Use port 8001 instead of post. The consumer server is OK
    @RequestMapping(value = "/add")
    public boolean add(@RequestBody Dept dept) {
        System.out.println(dept.getDname());
        return service.addDept(dept);
    }

    @GetMapping("/byId/{id}")
    @HystrixCommand(fallbackMethod = "HystrixgetDeptById")// Use alternative methods when throwing exceptions
    public Dept getDeptById(@PathVariable(value = "id") int id) {
        Dept dept = service.getById(id);
        if (dept == null) {
            throw new RuntimeException("id=>" + id + "No trace of him.");
        }
        return dept;
    }

    @GetMapping("/getAll")
    public List<Dept> getAll(a) {
        return service.getAll();
    }

    // Alternate methods
    public Dept HystrixgetDeptById(int id) {
        return new Dept()
                .setDeptId(id)
                .setDname("id=>" + id + "No corresponding information, nul1--@Hystrix")
                .setDb_source("There is no corresponding data in the database"); }}Copy the code
  • Start the class
@EnableEurekaClient
/* Client-side convenient comments to enable the Eureka discovery configuration (especially). Use this (optional) if you want to discover and make sure you know it is the Eureka you want. All it does is turn on discovery and let automatic configuration find available Eureka classes (that is, you also need Eureka on the classpath). * /
@SpringBootApplication
@EnableCircuitBreaker// Turn on the fuse
public class DeptProvider_Hystrix_8001 {
    public static void main(String[] args) { SpringApplication.run(DeptProvider_Hystrix_8001.class,args); }}Copy the code

summary

Service degradation

  • When the overall resources are not enough, we should give up some services and put the main resources into the core services.

The sample

steps

  1. Import dependence
  2. In the API project implementation interface FallbackFactory, create a fallback instance
  3. Annotations on API services@FeignClientAdd parametersfallbackFactory = xxx.class(FallbackFactory implementation class)
  4. Configure application.yaml in the service consumer

feign.hystrix.enabled: true

  • Rely on
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
Copy the code

Implement FallbackFactory interface in API project

/ * return for backup instances of a given reason reason - usually with com.net flix. Hystrix. AbstractCommand. GetExecutionException () * /
@Component
public class DeptClientServiceFallbackFactory implements FallbackFactory<FeignDeptService> {
    @Override
    public FeignDeptService create(Throwable cause) {
        return new FeignDeptService(){// Implement the interface
            @Override
            public boolean addDept(Dept dept) {
                return false;
            }

            @Override
            public Dept getById(int id) {
                return new Dept()
                        .setDeptId(id).setDname("id=>"+id+"Cannot be queried")
                        .setDb_source("Server is down, will be on later.");
            }

            @Override
            public List<Dept> getAll(a) {
                List<Dept> list= new ArrayList<>();
                list.add(new Dept().setDname("Server is down, will be on later."));
                returnlist; }}; }}Copy the code

The service API

@Service
@FeignClient(value= "SPRINGCLOUD-PROVIDER-DEPT",fallbackFactory = DeptClientServiceFallbackFactory.class)/ / value = service id
public interface FeignDeptService {
    @RequestMapping(value = "/add")
    boolean addDept(@RequestBody Dept dept);
    @GetMapping("/byId/{id}")
    Dept getById(@PathVariable(value = "id") int id);
    @GetMapping("/getAll")
    List<Dept> getAll(a);
}
Copy the code
  • Service consumer startup class
@SpringBootApplication//(scanBasePackages = "com.cloud.service")
@EnableEurekaClient
@EnableFeignClients//(basePackages = {"com.cloud.service"})
// @componentScan (basePackages = "com.cloud.service")// @componentScan (basePackages = "com.cloud.service"
public class FeignDeptConsumer_80 {
    public static void main(String[] args) { SpringApplication.run(FeignDeptConsumer_80.class,args); }}Copy the code

summary

Service fuse: The service fuse is performed on the server.

Service degradation: When the server becomes unavailable, the service consumer becomes self-sufficient.

Breaker Dashboard

  • Only services with a circuit breaker can be monitored

steps

  1. Create the Hystrix Dashboard project
  2. Import dependencies, which the service provider and Dashboard will guide
  3. The configuration file
  4. Create the HystrixMetricsServlet on the server that you want to monitor

Create a Hystrix Dashboard project. Create a Hystrix Dashboard project

Rely on

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

Service providers conduct

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Copy the code

Hystrix Dashboard project startup class

@SpringBootApplication
@EnableHystrixDashboard

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

Configuration file application.yaml

server:
  port: 9001
hystrix:
  dashboard:
    proxy-stream-allow-list: 'localhost'
Copy the code

Starting 9001, visit http://localhost:9001/hystrix

The monitored server creates the HystrixMetricsServlet

@EnableEurekaClient
/* Client-side convenient comments to enable the Eureka discovery configuration (especially). Use this (optional) if you want to discover and make sure you know it is the Eureka you want. All it does is turn on discovery and let automatic configuration find available Eureka classes (that is, you also need Eureka on the classpath). * /
@SpringBootApplication
@EnableCircuitBreaker// Turn on the fuse
public class DeptProvider_Hystrix_8001 {
    public static void main(String[] args) {
        SpringApplication.run(DeptProvider_Hystrix_8001.class,args);
    }
    / / HystrixMetricsServlet increase
    @Bean
    public ServletRegistrationBean hystrixMetricsServlet(a){
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
        registrationBean.addUrlMappings("/actuator/hystrix.stream");
        returnregistrationBean; }}Copy the code

How to use

  • To access a@HystrixCommandAnnotation method,

This example is http://localhost/consumer/byId/1

  • And then visithttp://localhost:8001/actuator/hystrix.stream, the port number is accessed there@HystrixCommandThe method.

In this example, port 8001 has the fusing method

  • Type http://localhost:8001/actuator/hystrix.stream in the Dashboard page.

  • Finally appeared