SpringCloud circuit breaker Hystrix implementation

Background: In an actual microservice system, there are many services, and often one service needs to depend on another service. For example, in a large e-commerce system, the divided order service and payment service will be interdependent. situation, and if one of the services hangs up and the other service keeps requesting, it will definitely not get a response. In this way, long-term requests will accumulate, causing the service to collapse, which will paralyze the entire system. Such an architecture is quite More unstable than traditional architecture. In order to solve and deal with this problem, the fuse Hystrix appeared.

Table of contents

(1) Introduction

(2) Implementation method 

1.Ribbon

2. How to use feign 

(1) Introduction

Netflix created a library called Hystrix that implements the circuit breaker pattern . In a microservice architecture, there are usually multiple layers of service calls.

Service failures in lower-level services can lead to user cascading failures. When calls to a specific service reach a certain threshold (the default in Hystrix is ​​20 failures in 5 seconds), the circuit is opened and no calls are made. Developers can provide fallbacks in case of bugs and open circuits. 

Open circuits stop cascading failures and allow unnecessary or failed service time to heal. The fallback can be another Hystrix-protected call, static data, or a normal null value. Fallbacks may be chained, so the first fallback makes some other business call back to static data.

(2) Implementation method 

In springCloud, fuses can be implemented in two ways: Ribbon and Feign. The following are still based on the previous project: eureka implementation , Ribbon implementation , feign implementation

1.Ribbon

Add Hystrix dependency to the previous Ribbon project pom.xml

  <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

Add the hystrix annotation @EnableHystrix to the ribbon startup class

package com.cloud.ribbonservice;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
public class RibbonserviceApplication {

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

    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Bean
    public IRule ribbonRule() {
        return new RandomRule();	//这里配置策略,和配置文件对应
    }

}

Then add the @HystrixCommand(fallbackMethod = "portFallback") annotation to the calling method, and add the callback method portFallback after circuit breaking.

package com.cloud.ribbonservice.service;

import com.cloud.ribbonservice.controller.Controller;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;

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

@Service
public class RibbonService implements IRibbonService {

    private static final Logger logger = LoggerFactory.getLogger(IRibbonService.class);

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    LoadBalancerClient loadBalancerClient;

    @HystrixCommand(fallbackMethod = "portFallback")
    public String port() {
        this.loadBalancerClient.choose("SPRING-CLIENT-01");
        String info = restTemplate.getForObject("http://SPRING-CLIENT-01/getInfo/port", String.class);
        return restTemplate.getForObject("http://SPRING-CLIENT-01/getInfo/port", String.class);

    }

    private String portFallback()
    {
        logger.error("The service is Down");
        System.err.println("The service is Down");
        return "Service down";
    }

   

}

The basics are now configured.

Then start the registration center, SPRING-CLIENT-01 service, and ribbon service.

Enter in the browser or postman

http://localhost:11000/getInfo/hellol

 

Close the SPRING-CLIENT-01 service and refresh the browser

The circuit breaker was triggered successfully.

2. How to use feign 

1. Add Hystrix dependency  to pom.xml in the previous feign project

2. Turn on the Hystrix switch  feign.hystrix.enabled=true in feign's configuration file application.properties file

server.port = 10010

eureka.client.serviceUrl.defaultZone= http://localhost:12345/eureka/
spring.application.name= SPRING-FEIGN-SERVICE


spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testmysql
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5

feign.hystrix.enabled=true

Add a fuse class to the calling interface. This class must implement the interface that previously called other services.

package com.springcloudfeign.feign.service;

import org.springframework.stereotype.Component;

@Component
public class ErrorHystrix implements FeignDemoService {

    @Override
    public String getPort() {
        return "sorry, it's error!";
    }

    @Override
    public String getPortTwo() {
        return "sorry, it's also error!";
    }


}

Then add the annotation of the fuse callback class to the FeignDemoService interface annotation @FeignClient(value = "SPRING-CLIENT-01", fallback = ErrorHystrix.class)

package com.springcloudfeign.feign.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@FeignClient(value = "SPRING-CLIENT-01" ,fallback = ErrorHystrix.class)
public interface FeignDemoService {

    @RequestMapping(value = "port" , method = RequestMethod.GET)
    String getPort();

    @RequestMapping(value = "getInfo/show" , method = RequestMethod.GET)
    String getPortTwo();
}

that's it.

SPRING-SERVICE-01 has nothing to do with the method of calling the interface in feign and the return is:

Enter in the browser:

http://localhost:10010/getInfoTwo

return:

Disconnect the SPRING-SERVICE-01 service, refresh the browser and return:

Indicates that the fuse call is successful.

Github address of the above code:  Source code address

 

 

 

 

 

 

 

 

Guess you like

Origin blog.csdn.net/harryptter/article/details/88077753