12. Feign Integrated Circuit Breaker Hystrix

Posted by eabigelow on Sat, 03 Aug 2019 17:28:35 +0200

Public number: java paradise

The first edition of RestTemplate+Ribbon Integrated Circuit Breaker Hystrix, this article to see how Feign Integrated Circuit Breaker Hystrix, Feign Integrated Circuit Breaker Hystrix is relatively simple. Feign has its own circuit breaker Hystrix by default, so you don't need to add annotations to SpringBook's boot class as RestTemplate+Ribbon Integrated Circuit Breaker Hystrix does. But Feign's own circuit breaker has not been turned on and additional configuration is needed.

feign:
     hystrix:
         enabled: true

1. New project sc-eureka-client-consumer-feign-hystrix, corresponding pom.xml file is as follows

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>spring-cloud</groupId>
    <artifactId>sc-eureka-client-consumer-feign</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>sc-eureka-client-consumer-feign</name>
    <url>http://maven.apache.org</url>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
    </parent>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

        </dependencies>
    </dependencyManagement>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>

        <!-- The explanation is one eureka client -->
        <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>

        <!-- <dependency> 
                        <groupId>org.springframework.cloud</groupId> 
                        <artifactId>spring-cloud-starter-feign</artifactId> 
                    <version>1.4.5.RELEASE</version> 
             </dependency> -->

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

    </dependencies>
</project>

Note: From the continuation relationship, we can see that spring-cloud-starter-openfeign has integrated circuit breaker Hystrix

2. New springboot Startup Class

package sc.consumer;

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

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class ConsumerFeignApplication {

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

}

3. New configuration files bootstrap.yml and application.yml
bootstrap.yml

server:
    port: 5800

application.yml

spring:
    application:
        name: sc-eureka-client-consumer-feign-hystrix

eureka:
    client:
        registerWithEureka: true #Whether to register yourself in the Eureka service by default to true
        fetchRegistry: true #Whether to get registration information from Eureka, default is true
        serviceUrl:
            defaultZone: http://localhost:5001/eureka/

feign:
    hystrix:
enabled: true

Description: A configuration item for opening Hystrix circuit breaker has been added to the application.yml configuration file.


4. New Service Consumer Class UserService.java

package sc.consumer.service;

import java.util.Map;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import sc.consumer.model.User;
import sc.consumer.service.hystrix.UserServiceHystrix;

@FeignClient(value="sc-eureka-client-provider", fallback=UserServiceHystrix.class)
public interface UserService {

    @GetMapping("/user/getUser/{id}")
    Map<String, Object> getUser(@PathVariable(value ="id") Long id);

    @RequestMapping("/user/listUser")
    Map<String, Object> listUser();

    @PostMapping("/user/addUser")
    Map<String, Object> addUser(@RequestBody User user);

    @PutMapping("/user/updateUser")
    Map<String, Object> updateUser(@RequestBody User user);

    @DeleteMapping("/user/deleteUser/{id}")
    Map<String, Object> deleteUser(@PathVariable(value ="id") Long id);

}

You can see that an attribute fallback has been added to the FeignClient annotation for this class


5. New Circuit Breaker Processing Class UserService Hystrix. Java

package sc.consumer.service.hystrix;

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

import org.springframework.stereotype.Component;

import sc.consumer.model.User;
import sc.consumer.service.UserService;

@Component
public class UserServiceHystrix  implements UserService{

    @Override
    public Map<String, Object> getUser(Long id) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("code", "000000");
        result.put("msg", "success");
        User u = new User();
        u.setId(-1L);
        u.setUserName("failBackName");
        result.put("body", u);
        return result;
    }

    @Override
    public Map<String, Object> listUser() {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("code", "000000");
        result.put("msg", "success");
        List<User> list = new ArrayList<User>();
        User u = new User();
        u.setId(-1L);
        u.setUserName("failBackName");
        list.add(u);
        result.put("body", list);
        return result;
    }

    @Override
    public Map<String, Object> addUser(User user) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("code", "000000");
        result.put("msg", "success");
        result.put("body", 0);
        return result;
    }

    @Override
    public Map<String, Object> updateUser(User user) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("code", "000000");
        result.put("msg", "success");
        result.put("body", 0);
        return result;
    }

    @Override
    public Map<String, Object> deleteUser(Long id) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("code", "000000");
        result.put("msg", "success");
        result.put("body", 0);
        return result;
    }

}

This class implements the UserService interface and implements all the methods of the interface.

6. Start registry sc-eureka-server and service provider sc-eureka-client-provider respectively

7. Start sc-eureka-client-consumer-feign-hystrix and verify that the startup is successful
Way 1: Look at the log to see if the corresponding port is booted

Way 2: Check whether the registry has registered successfully

8. Verify whether the circuit breaker is enabled using postman
In the previous part, I started from the service provider to verify whether the circuit breaker started properly. Today, I will check whether the circuit breaker started from the database to verify whether the circuit breaker started or not.
(1) When MySQL service starts normally, access:
http://127.0.0.1:5800/feign/user/listUser


(2) Access when MySQL service is closed
http://127.0.0.1:5800/feign/user/listUser

Look at the background log again:


Other interfaces can verify themselves in the above way to see if the circuit breaker is started.

Source code https://gitee.com/hjj520/spring-cloud-2.x

Topics: Java Spring Maven Apache