SpringCloud踩坑记(六)SpringCloud熔断器Hystrix

什么是Hystrix?

在分布式环境中,不可避免地会有许多服务依赖项中的某些失败。
Hystrix是一个库,可通过添加等待时间容限和容错逻辑来帮助您控制
这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点,
停止服务之间的级联故障并提供后备选项来实现此目的,
所有这些都可以提高系统的整体弹性。

Hystrix的作用是什么?

Hystrix旨在执行以下操作:

  • 提供保护并控制通过第三方客户端库访问(通常是通过网络)的依赖项带来的延迟和失败。
  • 停止复杂的分布式系统中的级联故障。
  • 快速失败并快速恢复。
  • 回退并在可能的情况下正常降级。
  • 启用近乎实时的监视,警报和操作控制。

Hystrix如何实现?

  • 资源隔离模式

    在一个高度服务化的系统中,我们实现一个业务功能,可能需要依赖多个第三方服务,
    如果第三方服务有出现不可用,这样导致我们业务服务线程就会阻塞等待。当大量的线程
    进入阻塞等待,引发整个服务不可用,这种相当可怕。

    Hystrix提供Bulkheads(舱壁隔离模式)进行将每个依赖服务分配独立的线程池进行资源隔离, 从而避免服务雪崩。

  • 熔断器模式

    熔断器模式是使用状态机进行状态切换控制,大致流程如下:

    SpringCloud踩坑记(六)SpringCloud熔断器Hystrix_第1张图片

  • 命令模式

    Hystrix使用命令模式(继承HystrixCommand类)来包裹具体的服务调用逻辑(run方法), 并在命令模式中添加了服务调用失败后的降级逻辑(getFallback)。同时我们在Command的构造方法中可以定义当前服务线程池和熔断器的相关参数。

  • 观察者模式

    Hystrix通过观察者模式对服务进行状态监听。每个任务都包含有一个对应的Metrics,所有Metrics都由一个ConcurrentHashMap来进行维护,Key是CommandKey.name()。在任务的不同阶段会往Metrics中写入不同的信息,Metrics会对统计到的历史信息进行统计汇总,供熔断器以及Dashboard监控时使用。

Ribbon + RestTemplate 使用Hystrix

复用之前Eureka注册的工程,修改EurekaClientConsumer工程相关内容。

pom.xml文件增加如下依赖:

<dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-hystrixartifactId>
        dependency>

启动类增加@EnableHystrix注解,并且修改MessageController类增加
出错处理方法,最终MessageController类内容如下:

@RestController
public class MessageController {
    @Autowired
    RestTemplate restTemplate;

    @GetMapping("/show")
    @HystrixCommand(fallbackMethod = "error")
    public String showMessage(@RequestParam String name){
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.add("token", "IT_LiGe");
        //producer 为提供的服务注入到eureka的名称
        return (restTemplate.exchange("http://producer/get?name="+name,
                HttpMethod.GET,new HttpEntity<String>(requestHeaders), String.class)).getBody();
    }

    public String error(String name) {
        return name + "error!";
    }
}

启动俩个提供服务工程,访问http://127.0.0.1:8600/show?name=IT_LiGe,显示如下:

Hi IT_LiGe ,I am from port:8001,token:IT_LiGe_Token
或者
Hi IT_LiGe ,I am from port:8002,token:IT_LiGe_Token

不启动俩个提供服务工程,访问http://127.0.0.1:8600/show?name=IT_LiGe,restTemplate发起请求出现错误,进入error方法,所以界面显示如下:

IT_LiGeerror!

Feign 使用Hystrix

复用之前Eureka注册的工程,修改EurekaClientFeign工程相关内容。
application.yal配置文件增加如下内容:

feign:
  hystrix:
    enabled: true

增加熔断回调类MessagesFeignFallback,内容如下:

@Component
public class MessagesFeignFallback implements MessagesFeignClient {
    @Override
    public String getName(String name) {
        return name +"error";
    }
}

进行修改使用@FeignClient注解的MessagesFeignClient类。最终类内容如下:

@FeignClient(name = "producer",fallback = MessagesFeignFallback.class)
public interface MessagesFeignClient {
    @GetMapping(value = "/get")
    String getName(@RequestParam(value = "name") String name);
}

如果需要使用错误内容进行判断可使用fallbackFactory参数。
例如:

@Component
public class HystrixClientFallbackFactory implements FallbackFactory<MessagesFeignClient> {
 
    @Override
    public MessagesFeignClient create(Throwable arg0) {
        // TODO Auto-generated method stub
        return new MessagesFeignClient() {
 
            @Override
            public String getName(String name) {

                return name +"error";
            }
             
        };
    }
 
}

修改完成后,不启动俩个提供服务工程,访问http://127.0.0.1:8700/show?name=IT_LiGe请求出现错误,进入error方法,所以界面显示如下:

  IT_LiGeerror!

Hystrix监控面板

Ribbon + RestTemplate

修改EurekaClientConsumer工程相关内容。

pom.xml增加如下依赖:

<dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-netflix-hystrix-dashboardartifactId>
        dependency>

启动类增加@EnableHystrixDashboard注解启动面板并且增加一个Servlet。最终完整代码如下:

@SpringBootApplication
@RibbonClient(name = "producer", configuration = MyRule.class)
@EnableHystrix
@EnableHystrixDashboard
public class EurekaClientConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaClientConsumerApplication.class, args);
    }


    @LoadBalanced //使用负载均衡机制
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    @Bean
    public ServletRegistrationBean getServlet(){
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/actuator/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }
}

启动服务,访问http://127.0.0.1:8600/hystrix,显示Hystrix Dashboard。

通过 Hystrix Dashboard 主页面的文字介绍,我们可以知道,Hystrix Dashboard 共支持三种不同的监控方式:

  • 默认的集群监控:通过 URL:http://turbine-hostname:port/turbine.stream 开启,实现对默认集群的监控。
  • 指定的集群监控:通过 URL:http://turbine-hostname:port/turbine.stream?cluster=[clusterName] 开启,实现对 clusterName 集群的监控。
  • 单体应用的监控: 通过 URL:http://hystrix-app:port/actuator/hystrix.stream 开启 ,实现对具体某个服务实例的监控。

页面上的另外两个参数:

  • Delay:控制服务器上轮询监控信息的延迟时间,默认为 2000 毫秒,可以通过配置该属性来降低客户端的网络和 CPU 消耗。
  • Title:该参数可以展示合适的标题。

我们输入http://127.0.0.1:8600/actuator/hystrix.stream,2000,IT_LiGe然后点击Monitor Stream。
我们发现界面显示Loading状态,这时候我们另外开一个界面访问http://127.0.0.1:8600/show?name=IT_LiGe,
然后再刷新之前的界面,这时我们就可以看到统计的信息。

界面显示字段内容图解如下:

SpringCloud踩坑记(六)SpringCloud熔断器Hystrix_第2张图片

Feign

与上面除了端口号之外,其他内容一致,就不重复说明。

附录

Hystrix已经不再处于主动开发中,并且当前处于维护模式,但是不影响使用。

官网给的解释:

Hystrix(1.5.18版)足够稳定,可以满足Netflix现有应用程序的需求。
同时,我们的重点已转向对应用程序的实时性能做出反应的自适应性实现,
而不是预先配置的设置(例如,通过自适应并发限制)。对于像Hystrix
这样有意义的情况,我们打算继续将Hystrix用于现有应用程序,并为新的
内部项目利用诸如resilience4j之类的开放式活动项目。我们开始建议其
他人也这样做。

附录

源代码地址:https://gitee.com/LeeJunProject/spring_cloud_learning/tree/master/eureka/EurekaDemo

END

欢迎扫描下图关注公众号 IT李哥,公众号经常推送一些优质的技术文章

在这里插入图片描述

你可能感兴趣的:(SpringCloud)