Spring cloud fuse Hystrix and service monitoring Dashboard

Service avalanche effect


When there are problems such as inaccessibility, exception and timeout in the requested service, the user's request will be blocked and other functions will be affected,


If there are unreachable services in the requests of multiple users, they will all fall into a blocked state.

Service fuse service degradation

Introduction to Hystrix circuit breaker

The Chinese name of hystrix is "porcupine". Porcupine is covered with thorns, which can protect itself from natural enemies. It represents a defense mechanism, which coincides with the function of hystrix itself. Therefore, Netflix team named the framework hystrix and used the corresponding cartoon image as the logo.

In a distributed system, many dependencies inevitably fail to call, such as timeout, exception, etc. How to ensure that in the case of a dependency failure, the whole service will not fail? This is what hystrix needs to do. Hystrix provides functions such as fusing, isolation, Fallback, cache, monitoring, etc., which can ensure the system is still available when one or more dependencies have problems at the same time.

Hystrix service fuse service degraded @ HystrixCommand fallbackMethod

Fusing mechanism is a micro service link protection mechanism to deal with avalanche effect.
When a service is unavailable or the response time is timeout, the service will be degraded, and then the service call of the node will be fused to quickly return the customized error impact page information.

Quick failure return
If the service fuse is not handled
1001, 1102, 1003
If 1002 fails, it will take 5s for the browser to return data
For service fusing
If 1002 fails and no data is returned after 2s, the service fuse will be degraded automatically and the user-defined error page information will be returned quickly

Let's write a project to test;

We write a new service provider project with service fuse microservice-student-provider-hystrix-1004
Copy the configuration and code into the project;

pom.xml plus hystrix support

<!--Hystrix Dependent dependence-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>

application.yml modify the lower port and instance name

server:
  port: 1004
  context-path: /
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis_ssm?useUnicode=true&characterEncoding=utf8
    username: mybatis_ssm
    password: xiaoli
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
  application:
    name: microservice-student
  profiles: provider-hystrix-1004

eureka:
  instance:
    hostname: localhost
    appname: microservice-student
    instance-id: microservice-student:1004
    prefer-ip-address: true
  client:
    service-url:
      defaultZone: http://eureka2001.xhh.com:2001/eureka/,http://eureka2002.xhh.com:2002/eureka/,http://eureka2003.xhh.com:2003/eureka/

info:
  groupId: com.xhh.testSpringcloud
  artifactId: microservice-student-provider-hystrix-1004
  version: 1.0-SNAPSHOT
  userName: http://xhh.com
  phone: 123456

The startup class studentproviderhystrixapplication_isannotated to support @ EnableCircuitBreaker

package com.xhh.microservicestudentproviderhystrix1004;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@EnableCircuitBreaker
@EntityScan("com.xhh.*.*")
@EnableEurekaClient
@SpringBootApplication
public class MicroserviceStudentProviderHystrix1004Application {

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

}

New controller in service provider 1004
If StudentProviderController's hystrix() executes for more than a second, it will go to the hystrixFallback() method and return the error message

package com.xhh.microservicestudentproviderhystrix1004.controller;Would call

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.xhh.microservicecommon.entity.Student;
import com.xhh.microservicestudentproviderhystrix1004.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/student")
public class StudentProviderController {
 
    @Autowired
    private StudentService studentService;
    @Value("${server.port}")
    private String port;
     
    @PostMapping(value="/save")
    public boolean save(Student student){
        try{
            studentService.save(student);  
            return true;
        }catch(Exception e){
            return false;
        }
    }
     
    @GetMapping(value="/list")
    public List<Student> list(){
        return studentService.list();
    }
     
    @GetMapping(value="/get/{id}")
    public Student get(@PathVariable("id") Integer id){
        return studentService.findById(id);
    }
     
    @GetMapping(value="/delete/{id}")
    public boolean delete(@PathVariable("id") Integer id){
        try{
            studentService.delete(id);
            return true;
        }catch(Exception e){
            return false;
        }
    }

    @RequestMapping("/ribbon")
    public String ribbon(){
        return "Job number ["+port+"]Serving you";
    }

    /**
     * Test Hystrix service degradation
     * @return
     * @throws InterruptedException
     */
    @ResponseBody
    @GetMapping(value="/hystrix")
    @HystrixCommand(fallbackMethod="hystrixFallback")
    public Map<String,Object> hystrix() throws InterruptedException{
//        Thread.sleep(2000);
        Map<String,Object> map=new HashMap<String,Object>();
        map.put("code", 200);
        map.put("info","Job number ["+port+"]Serving you");
        return map;
    }

    public Map<String,Object> hystrixFallback() throws InterruptedException{
        Map<String,Object> map=new HashMap<String,Object>();
        map.put("code", 500);
        map.put("info", "System ["+port+"]Busy, try again later");
        return map;
    }
}

Service consumers
microservice-student-consumer-80 project also needs to add corresponding methods

 @GetMapping(value="/hystrix")
    @ResponseBody
    public Map<String,Object> hystrix(){
        return restTemplate.getForObject(SERVER_IP_PORT+"/student/hystrix/", Map.class);
    }

Then let's test it
First start three eureka, then start the provider with hystrix, and finally start the normal consumer;

Browser: http://localhost/student/hystrix

Default timeout setting of Hystrix

The default timeout of hystrix is 1 second. We can see it through the hystrix source code,
Find the HystrixCommandProperties class under the package hystrix-core.jar com.netflix.hystrix
 Default? Executiontimeoutinmilliseconds property default timeout for situations

Default 1000 ms 1 sec

If we want to customize the default time of hystrix in our system;

application.yml configuration file plus

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000


Hystrix service monitoring Dashboard

Dashboard for Hystrix service monitoring

Hystrix provides a quasi real-time service call monitoring project Dashboard, which can record the execution of requests initiated through hystrix in real time,
It can be displayed to users in the form of charts.

Our new project: microservice-student-consumer-hystrix-dashboard-90
Plus dependency:

<!--Hystrix Service monitoring Dashboard rely on-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

application.yml

server:
  port: 90
  context-path: /

New startup class: studentconsumerdashboardapplication
Note: @ EnableHystrixDashboard

Then we start the project;
Then the browser enters: http://localhost:90/hystrix


If this appears, it means OK;

Then let's test it;

Let's start three eureka s and then microservice-student-provider-hystrix-1004

We input the project and method path to be monitored
We directly request http://localhost:1004/student/hystrix

74 original articles published, 6 praised, 2791 visited
Private letter follow

Tags: Spring Java MySQL JDBC

Posted on Sat, 11 Jan 2020 05:08:32 -0800 by Rushyo