springcloud-熔断器(Hystrix)

大数据44

Hystrix在cloud有两种使用方式,我感觉有三种。

1、Hystrix+ribbon;

2、Hystrix+feign;

3、zuul(集成的降级处理机制)-后面zuul会提到;

首先创建一个hystrix模块。

springcloud-熔断器(Hystrix)

再创建hystrixribbon、hystrixfeign模块。

一、hystrix配合ribbon

项目工程如下:

springcloud-熔断器(Hystrix)

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelversion>4.0.0</modelversion>
    <parent>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-parent</artifactid>
        <version>2.3.2.RELEASE</version>
    </parent>
    <groupid>com.cloud</groupid>
    <artifactid>hystrixribbon</artifactid>
    <version>0.0.1-SNAPSHOT</version>
    <name>hystrixribbon</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR9</spring-cloud.version>
        <spring-cloud-alibaba.version>2.2.6.RELEASE</spring-cloud-alibaba.version>
    </properties>
    <dependencies>
        <!--eureka客户端-->
        <dependency>
            <groupid>org.springframework.cloud</groupid>
            <artifactid>spring-cloud-starter-netflix-eureka-client</artifactid>
            <version>1.4.6.RELEASE</version>
        </dependency>
        <!--熔断器-->
        <dependency>
            <groupid>org.springframework.cloud</groupid>
            <artifactid>spring-cloud-starter-hystrix</artifactid>
            <version>1.4.4.RELEASE</version>
        </dependency>

    </dependencies>
    <!--指定下载源和使用springcloud的版本-->
    <dependencymanagement>
        <dependencies>
            <dependency>
                <groupid>org.springframework.cloud</groupid>
                <artifactid>spring-cloud-dependencies</artifactid>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupid>com.alibaba.cloud</groupid>
                <artifactid>spring-cloud-alibaba-dependencies</artifactid>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencymanagement>
    <build>
        <plugins>
            <plugin>
                <groupid>org.springframework.boot</groupid>
                <artifactid>spring-boot-maven-plugin</artifactid>
            </plugin>
        </plugins>
    </build>

</project>

application.yml

spring:
  application:
    name: service-ribbon-hystrix  #&#x670D;&#x52A1;&#x5E94;&#x7528;&#x540D;&#x79F0;
server:
  port: 8088 #&#x670D;&#x52A1;&#x7AEF;&#x53E3;&#x53F7;

eureka:
  client:
    healthcheck:
      enabled: false #&#x542F;&#x52A8;&#x670D;&#x52A1;&#x5065;&#x5EB7;&#x72B6;&#x6001;&#x7684;&#x68C0;&#x67E5;
    serviceUrl:
      defaultZone:  http://localhost:8090/eureka #&#x6CE8;&#x518C;&#x670D;&#x52A1;&#x7EC4;&#x4EF6;&#x7684;url
  instance:
    prefer-ip-address: true #&#x4F7F;&#x7528;ip&#x524D;&#x7F00;

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000 #&#x7194;&#x65AD;&#x7684;&#x8D85;&#x65F6;&#x65F6;&#x95F4;
HystrixribbonApplication.java(作为客户端注册到注册中心。增加熔断器注解@EnableCircuitBreaker)
package com.cloud.hystrixribbon;

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

@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public class HystrixribbonApplication {

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

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

}

TestController

package com.cloud.hystrixribbon.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * <b>&#x6280;&#x672F;&#x652F;&#x6301;&#xFF1A;</b> (c)
 *
 * @author lx.w
 * @version 1.0
 * @since JDK1.8
 */
@RestController
@RequestMapping("/hystrix/ribbon")
public class TestController {

    @Autowired
    private RestTemplate restTemplate;

    @PostMapping("/test")
    @HystrixCommand(fallbackMethod = "fallTest")
    public String test(@RequestParam String s) {
        String str = restTemplate.postForObject("http://client-service/client/hello/world?str=" + s, null, String.class);
        System.out.println("hystrixRibbon");
        return str + " hystrixRibbon";
    }

    /**
     * @desc: &#x7194;&#x65AD;&#x964D;&#x7EA7;&#x65B9;&#x6CD5;
     * @author: lx.w
     * @params: params
     */
    private String fallTest(String s) {
        System.out.println("&#x8FDB;&#x5165;&#x7194;&#x65AD;&#x964D;&#x7EA7;&#x65B9;&#x6CD5;");
        return "no Service" + s;
    }

}

注意看这个TestController的test方法,在头部增加了熔断器的注解@HystrixCommand(fallbackMethod = "fallTest"),通过该注解,当调用的下游服务不可用时,请求会回调到fallbackMethod指定的方法中。

postman直接访问hystrixribbon服务的test接口

当下游服务正常运行时

springcloud-熔断器(Hystrix)

当下游服务停止时(此时配置在@HystrixCommand(fallbackMethod = "fallTest")中方法fallTest设置的返回值返回)

springcloud-熔断器(Hystrix)

二、hystrix配合feign

项目工程如下:

springcloud-熔断器(Hystrix)

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelversion>4.0.0</modelversion>
    <parent>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-parent</artifactid>
        <version>2.3.2.RELEASE</version>
    </parent>
    <groupid>com.cloud</groupid>
    <artifactid>hystrixfeign</artifactid>
    <version>0.0.1-SNAPSHOT</version>
    <name>hystrixfeign</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR9</spring-cloud.version>
        <spring-cloud-alibaba.version>2.2.6.RELEASE</spring-cloud-alibaba.version>
    </properties>
    <dependencies>
        <!--eureka客户端-->
        <dependency>
            <groupid>org.springframework.cloud</groupid>
            <artifactid>spring-cloud-starter-netflix-eureka-client</artifactid>
            <version>1.4.6.RELEASE</version>
        </dependency>
        <!--熔断器-->
        <dependency>
            <groupid>org.springframework.cloud</groupid>
            <artifactid>spring-cloud-starter-hystrix</artifactid>
            <version>1.4.4.RELEASE</version>
        </dependency>
        <!--feign-->
        <dependency>
            <groupid>org.springframework.cloud</groupid>
            <artifactid>spring-cloud-starter-openfeign</artifactid>
        </dependency>
    </dependencies>
    <!--指定下载源和使用springcloud的版本-->
    <dependencymanagement>
        <dependencies>
            <dependency>
                <groupid>org.springframework.cloud</groupid>
                <artifactid>spring-cloud-dependencies</artifactid>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupid>com.alibaba.cloud</groupid>
                <artifactid>spring-cloud-alibaba-dependencies</artifactid>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencymanagement>
    <build>
        <plugins>
            <plugin>
                <groupid>org.springframework.boot</groupid>
                <artifactid>spring-boot-maven-plugin</artifactid>
            </plugin>
        </plugins>
    </build>

</project>

application.yml(比hystrix+ribbon多了一个feign.hystrix.enabled=true feign熔断器开启的配置)

spring:
  application:
    name: service-feign-hystrix  #&#x670D;&#x52A1;&#x5E94;&#x7528;&#x540D;&#x79F0;
server:
  port: 8087 #&#x670D;&#x52A1;&#x7AEF;&#x53E3;&#x53F7;

eureka:
  client:
    healthcheck:
      enabled: false #&#x542F;&#x52A8;&#x670D;&#x52A1;&#x5065;&#x5EB7;&#x72B6;&#x6001;&#x7684;&#x68C0;&#x67E5;
    serviceUrl:
      defaultZone:  http://localhost:8090/eureka #&#x6CE8;&#x518C;&#x670D;&#x52A1;&#x7EC4;&#x4EF6;&#x7684;url
  instance:
    prefer-ip-address: true #&#x4F7F;&#x7528;ip&#x524D;&#x7F00;
##&#x5F00;&#x542F;feign&#x7684;&#x7194;&#x65AD;&#x5668;hystrix
feign:
  hystrix:
    enabled: true

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000 #&#x7194;&#x65AD;&#x7684;&#x8D85;&#x65F6;&#x65F6;&#x95F4;

HystrixfeignApplication.java

package com.cloud.hystrixfeign;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * <b>&#x6280;&#x672F;&#x652F;&#x6301;&#xFF1A;</b>  (c)
 *
 * @author lx.w
 * @version 1.0
 * @since JDK1.8
 */
@EnableFeignClients
@EnableDiscoveryClient
@EnableCircuitBreaker
@SpringBootApplication
public class HystrixfeignApplication {

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

}

在FeignService中添加的注解

@FeignClient中有属性fallbackFactory作为熔断降级属性,也可以使用fallback作为熔断降级属性。即存在两种熔断降级的配置方法。
package com.cloud.hystrixfeign.feign;

import com.cloud.hystrixfeign.feign.fallback.HystrixClientFallBack;
import com.cloud.hystrixfeign.feign.fallback.HystrixClientFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * <b>&#x6280;&#x672F;&#x652F;&#x6301;&#xFF1A;</b>  (c)
 *
 * @author lx.w
 * @version 1.0
 * @since JDK1.8
 */
@FeignClient(value = "client-service", fallbackFactory = HystrixClientFallbackFactory.class)
public interface FeignService {

    @PostMapping("/client/hello/world")
    String helloWorld(@RequestParam("str") String str);

}

TestController.java

package com.cloud.hystrixfeign.controller;

import com.cloud.hystrixfeign.feign.FeignService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * <b>&#x6280;&#x672F;&#x652F;&#x6301;&#xFF1A;</b> (c)
 *
 * @author lx.w
 * @version 1.0
 * @since JDK1.8
 */
@RestController
@RequestMapping("/hystrix/feign")
public class TestController {

    @Autowired
    private FeignService feignService;

    @PostMapping("/test")
    public String test(@RequestParam String s) {
        System.out.println("hystrixFeign");
        return feignService.helloWorld(s) + " hystrixFeign";
    }

}

接下来是关键点了,在FeignService中有两种熔断降级的配置方法。首先先讲第一种fallbackFactory。在FeignService的类中,注解@FeignClient(value = "client-service", fallbackFactory = HystrixClientFallbackFactory.class) 使用到的属性为fallbackFactory。

同时需要配置以下两个配置类:

1、HystrixClientWithFallbackFactory

package com.cloud.hystrixfeign.feign.fallback;

import com.cloud.hystrixfeign.feign.FeignService;

public interface HystrixClientWithFallbackFactory extends FeignService {

}

2、HystrixClientFallbackFactory

package com.cloud.hystrixfeign.feign.fallback;

import com.cloud.hystrixfeign.feign.FeignService;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;

@Component
public class HystrixClientFallbackFactory implements FallbackFactory<feignservice> {

    @Override
    public FeignService create(Throwable arg0) {
        // TODO Auto-generated method stub
        return new HystrixClientWithFallbackFactory() {

            @Override
            public String helloWorld(String str) {
                return "error client ";
            }
        };
    }

}
</feignservice>

使用postman直接访问接口http://localhost:8087/hystrix/feign/test

当调用下游服务正常运行时

springcloud-熔断器(Hystrix)

当调用下游服务异常时(此时配置在HystrixClientFallbackFactory类中降级返回的参数返回)

springcloud-熔断器(Hystrix)

第二种配置@FeignClient(value = "client-service", fallback = HystrixClientFallBack.class)使用到的属性为fallback(需要将第一种配置类HystrixClientFallbackFactory的配置注解@Component注释下)

配置类HystrixClientFallBack.java

package com.cloud.hystrixfeign.feign.fallback;

import com.cloud.hystrixfeign.feign.FeignService;
import org.springframework.stereotype.Component;

/**
 * <b>&#x6280;&#x672F;&#x652F;&#x6301;&#xFF1A;</b>  (c)
 *
 * @author lx.w
 * @version 1.0
 * @since JDK1.8
 */
@Component
public class HystrixClientFallBack implements FeignService {

    @Override
    public String helloWorld(String str) {
        System.out.println("&#x8FDB;&#x5165;&#x7194;&#x65AD;&#x964D;&#x7EA7;");
        return "error client " + str;
    }
}

使用postman直接访问接口http://localhost:8087/hystrix/feign/test

当调用下游服务正常运行时

springcloud-熔断器(Hystrix)

当调用下游服务异常时(此时配置在HystrixClientFallbackFactory类中降级返回的参数返回)

springcloud-熔断器(Hystrix)

思考一下,hystrix+ribbon与hystrix+feign两种组合,第一种组合个人觉得好像不怎么适用,他涉及到服务自己去做熔断降级的措施,我理解在微服务中熔断降级应该统一管理(如果想法不对请在评论区留言讨论)。第二种 hystrix+feign在配置面上好像简单了很多,但是感觉还是有点个性化了。面对再对阿里的sentinel熔断器作深入探讨

Original: https://blog.csdn.net/Sorry_No_konw/article/details/123483231
Author: 哟,Liberty
Title: springcloud-熔断器(Hystrix)